параметр автоматического шаблона, элемент данных и постоянство

Предположим, у меня есть указатель на элемент данных, и я хочу знать, является ли он постоянным или нет. Другими словами:

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)>>;

Тем не менее, это выглядит уродливый для меня, и я чувствую, что должен быть лучший способ сделать это.
Есть ли другое (более короткое) решение для этого?

1

Решение

Вы могли бы изменить 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 параметр шаблона. Но, используя параметр типа, вы избегаете ненужных мгновений для разных указателей одного типа, что, предположительно, хорошо.

1

Другие решения

Как насчет чего-то вроде этого:

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>;

рабочий тест здесь

0

По вопросам рекламы [email protected]