如何检测类型别名?

4
我可以使用以下模板检查来检测成员:
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)是否有某种类型的using定义。也就是像这样:

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

在C++17中是否有可能实现这个?如何实现?


使用C++20的requires,两者都可以变成一行代码。 - HolyBlackCat
@HolyBlackCat 是的:我迫不及待地等待着我的云计算平台采用最新的GCC工具链的时刻。 - willem
1个回答

5
你可以使用与检测数据成员相同的方法来实现。不要使用数据成员,只需使用成员类型和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; }) {

}

演示链接


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接