C++两个is_union_or_class实现

C++ two is_union_or_class implementations

本文关键字:class 实现 or union is C++ 两个      更新时间:2023-10-16

我尝试实现is_union_or_class,首先没有使用以下方法void_t

#include <type_traits>
namespace detail {
template <class T>
struct is_union_or_class_helper1 : public std::false_type { };
template <class T>
struct is_union_or_class_helper1<char T::*> : public std::true_type { };
}
template <class T>
struct is_union_or_class1 : public detail::is_union_or_class_helper1<T> { };

然后我使用虚拟空类对其进行了测试,value成员评估为false.然后我使用如下void_t重试:

#include <type_traits>
template <class...>
using void_t = void;
namespace detail {
template <class T, class = void_t<T>>
struct is_union_or_class_helper2 : public std::false_type { };
template <class T>
struct is_union_or_class_helper2<T, void_t<char T::*>> : public std::true_type { };
}
template <class T>
struct is_union_or_class2 : public detail::is_union_or_class_helper2<T> { };

而这次它正确地评估为true.为什么结果不同?两个帮助器在char T::*是有效表达式的情况下都更专业,为什么只有第二种情况下的帮助程序从true_type继承?以下是测试代码:

struct dummy_type { };
int main(int argc, char** argv) {
std::cout << is_union_or_class1<dummy_type>::value << "n";
std::cout << is_union_or_class2<dummy_type>::value << "n";
}

我编译了这段代码并使用 MSVC 2015 编译器进行了测试。

考虑一下:

is_union_or_class1<dummy_type>::value

dummy_type不是指向要推断的类Tchar 类型的数据成员的指针。换句话说,dummy_type(让我说(与类型char T::*不匹配,则放弃此专业化。
因此,选择类模板并从std::false_type继承该类模板:

template <class T>
struct is_union_or_class_helper1 : public std::false_type { };

这样的东西会起作用:

template <class T, typename = T>
struct is_union_or_class_helper1 : public std::false_type { };
template <class T>
struct is_union_or_class_helper1<T, decltype((char T::*){}, T{})> : public std::true_type { };

这只不过是void_t成语的另一种变体。
让我重写一下:

template <class T, typename = void>
struct is_union_or_class_helper1 : public std::false_type { };
template <class T>
struct is_union_or_class_helper1<T, decltype((char T::*){}, void())> : public std::true_type { };

就是这样,对于那些仍在等待 C++17 的人来说,void_t成语的形式之一。