Предположим, у меня есть указатель на элемент данных, и я хочу знать, является ли он постоянным или нет. Другими словами:
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)>>;
Тем не менее, это выглядит уродливый для меня, и я чувствую, что должен быть лучший способ сделать это.
Есть ли другое (более короткое) решение для этого?
Вы могли бы изменить 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>;