首页 > 解决方案 > 如何检测类型类型别名?

问题描述

我可以使用以下模板检查来检测成员:

template <typename T, typename = void>
struct hasMember : std::false_type {};
template <typename T>
struct hasMember<T, decltype((void)T::member, void())> : std::true_type {};

例如:

class Test{
public:
   int member;
   using sometype = size_t; 
}

我可以:

if constexpr(hasMember<Test>)
{
   //do something
}

现在假设我需要一个constexpr if告诉我一个类是否有一个 using 定义。即可以检测到某个类(例如test)具有某种类型的使用定义的东西。即类似的东西

if constexpr(hasSomeType<Test>)
{
     //do something
} 

这在 c++17 中可行吗?如何?

标签: c++templatesc++17

解决方案


您可以使用与数据成员检测相同的方法来做到这一点。而不是使用数据成员,只需使用成员类型和void_t

template <typename T, typename = void>
struct hasSomeType : std::false_type {};

template <typename T>
struct hasSomeType<T, std::void_t<typename T::member_type>> : std::true_type {};

或者,您可以使用检测成语

template<typename T>
using member_type_t = typename T::member_type;

您可以使用 将任何表达式放在那里decltype

然后,使用别名执行检测:

if constexpr (is_detected<member_type_t, Test>) {
    // ...
}

当然,在 C++20 中,所有这些都变成了一个衬里:

// requires a type
if constexpr (requires(Test) { typename Test::member_type; }) {

}

// requires a member
if constexpr (requires(Test t) { t.member; }) {

}

活生生的例子


推荐阅读