自动模板参数,数据成员和常量

时间:2018-09-09 12:25:15

标签: c++ templates c++17 typetraits data-member-pointers

假设我有一个指向数据成员的指针,我想知道它是否为const。换句话说:

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的唯一方法是:

const auto bar = std::is_const_v<std::remove_reference_t<decltype(std::declval<Class>().*Member)>>;

但是,在我看来,丑陋,我觉得必须有更好的方法。
还有其他(更短的)解决方案吗?

2 个答案:

答案 0 :(得分: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 :(得分:0)

怎么样呢?

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

working test here