2015-05-04 127 views
3

说我有以下两个测试类:有模板成员 - 模板模板扣

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的第一个定义。

在此先感谢您的启示!

+1

将'TestYes :: type'更改为'int',并且您的第一个测试也会中断。这本质上是http://stackoverflow.com/questions/27687389/how-does-void-t-work –

回答

2
template<template<class...> class...> 
using void_templ = void; 

template <typename, typename = void> 
struct has_test_impl { 
    using type = std::false_type; 
}; 
template <typename T> 
struct has_test_impl<T, void_templ<T::template test>> { 
    using type = std::true_type; 
}; 
+0

感谢您的答案。使用gcc的版本4.9.2,我遇到了[这个问题](http://stackoverflow.com/questions/25833356/is-there-a-compiler-bug-exposed-by-my-implementation-of-an-is -complete-type-trai/25833474#25833474)你应该熟悉^^。适应模板模板,它的工作就像一个魅力。双倍感谢! :d –