Параметр автоматического шаблона, элемент данных и постоянство
Предположим, у меня есть указатель на элемент данных, и я хочу знать, является ли он постоянным или нет. Другими словами:
struct S {
const int i; // this is const
int j;
};
В C++ я делал что-то вроде этого:
template<typename Class, typename Type, Type Class:: *>
struct is_const_data_member: std::false_type {};
template<typename Class, typename Type, const Type Class:: *Member>
struct is_const_data_member<Class, const Type, Member>: std::true_type {};
template<typename Class, typename Type, Type Class:: *Member>
void foo() {
const auto bar = is_const_data_member<Class, Type, Member>::value;
// ...
}
Тем не менее, сейчас есть auto
Параметр шаблона и список параметров шаблона очень элегантны:
template<auto Member>
void foo() {
// ...
}
В этом случае единственный способ узнать, указывает ли элемент данных на что-то, что является постоянным:
const auto bar = std::is_const_v<std::remove_reference_t<decltype(std::declval<Class>().*Member)>>;
Тем не менее, это выглядит уродливо для меня, и я чувствую, что должен быть лучший способ сделать это.
Есть ли другое (более короткое) решение для этого?
2 ответа
Вы могли бы изменить is_const_data_member
работать с параметром шаблона одного типа:
template<typename MemPtr>
struct is_const_data_member: std::false_type {};
template<typename Class, typename Type>
struct is_const_data_member<const Type Class::*>: std::true_type {};
Тогда из template<typename Class, typename Type, Type Class:: *Member> void foo()
вы используете это как
is_const_data_member<Type Class::*>::value
(Что, на мой взгляд, немного более интуитивно понятно.)
И из template<auto Member> void foo()
вы используете это как
is_const_data_member<decltype(Member)>::value
Вы также можете переписать черту, чтобы работать на auto
параметр шаблона. Но, используя параметр типа, вы избегаете ненужных мгновений для разных указателей одного и того же типа, что предположительно хорошо.
Как насчет чего-то вроде этого:
template <typename T>
struct is_const_data_member : std::false_type {};
template <typename C, typename T>
struct is_const_data_member<const T C::*> : std::true_type {};
template <auto T>
constexpr bool is_const_data_member_v = is_const_data_member<decltype(T)>::value;
А потом, например
struct Test
{
int a;
const int b;
};
bool x = is_const_data_member_v<&Test::a>;
bool y = is_const_data_member_v<&Test::b>;