параметр автоматического шаблона, элемент данных и постоянство - PullRequest
0 голосов
/ 09 сентября 2018

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

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 ]

0 голосов
/ 09 сентября 2018

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

0 голосов
/ 09 сентября 2018

Как насчет этого:

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

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

...