【发布时间】:2015-05-04 03:46:29
【问题描述】:
假设我有以下两个测试类:
struct TestYes {
using type = void;
template <typename... T>
using test = void;
};
struct TestNo { };
我想确定他们是否有这个模板成员test。
对于会员type,
template <typename, typename = void>
struct has_type_impl {
using type = std::false_type;
};
template <typename T>
struct has_type_impl<T, typename T::type> {
using type = std::true_type;
};
template <typename T>
using has_type = typename has_type_impl<T>::type;
完美运行:
static_assert( has_type<TestYes>::value, ""); // OK
static_assert(!has_type<TestNo>::value, ""); // OK
但模板成员 test 的等效项:
template <typename, template <typename...> class = std::tuple>
struct has_test_impl {
using type = std::false_type;
};
template <typename T>
struct has_test_impl<T, T::template test> {
using type = std::true_type;
};
template <typename T>
using has_test = typename has_test_impl<T>::type;
失败
static_assert( has_test<TestYes>::value, "");
我知道我可以像这样使用 SFINAE:
template <typename T>
struct has_test_impl {
private:
using yes = std::true_type;
using no = std::false_type;
template <typename U, typename... Args>
static auto foo(int) -> decltype(std::declval<typename U::template test<Args...>>(), yes());
template <typename> static no foo(...);
public:
using type = decltype(foo<T>(0));
};
template <typename T>
using has_test = typename has_test_impl<T>::type;
但我想知道为什么编译器正确地扣除了 has_type_impl 的部分特化,而它仍然保留在 has_test_impl 的第一个定义上。
提前感谢您的启发!
【问题讨论】:
-
将
TestYes::type更改为int,您的第一个测试也会中断。这本质上是stackoverflow.com/questions/27687389/how-does-void-t-work
标签: c++ substitution template-templates