自动模板参数、数据成员和恒常性

auto template parameter, data member and constness

本文关键字:数据成员 常性 参数      更新时间:2023-10-16

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

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

但是,这对我来说看起来很丑,我觉得一定有更好的方法可以做到这一点。
还有其他(更短的(解决方案吗?

您可以更改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>;

工作测试在这里