1

假设我有一个指向数据成员的指针,我想知道它是否为 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)>>;

但是,它对我来说看起来很丑,我觉得必须有更好的方法来做到这一点。
有没有其他(更短的)解决方案?

4

2 回答 2

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模板参数进行操作。但是通过使用类型参数,您可以避免对相同类型的不同指针进行不必要的实例化,这被认为是一件好事。

于 2018-09-09T12:36:17.673 回答
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>;

工作测试在这里

于 2018-09-09T12:36:08.243 回答