C++ 为模板参数专门化可变模板类

C++ 为模板参数专门化可变模板类,c++,c++11,variadic-templates,template-specialization,C++,C++11,Variadic Templates,Template Specialization,我有以下元结构模板,用于检查特定类型(键类型KeyType)是否是参数包的一部分 #include <type_traits> #include <utility> template<typename ...> struct find_type : std::false_type {}; //specialization used if queried type is found template<typename QueriedType> s

我有以下元结构模板,用于检查特定类型(键类型
KeyType
)是否是参数包的一部分

#include <type_traits>
#include <utility>

template<typename ...>
struct find_type : std::false_type {};

//specialization used if queried type is found
template<typename QueriedType>
struct find_type<QueriedType, QueriedType> : std::true_type {};

//specialization used if KeyType and ValueType not wrapped
template<typename QueriedType,
         typename KeyType,
         typename ValueType,
         typename... Remaining>
struct find_type<QueriedType, KeyType, ValueType, Remaining...>
{
    static const bool value =
        std::conditional<find_type<QueriedType, KeyType>::value,
                         std::true_type,
                         find_type<QueriedType, Remaining...>>::type::value;
};

//specialization used if KeyType and ValueType are wrapped inside e.g. std::pair
template<typename QueriedType,
         template<typename, typename> class C,
         typename KeyType,
         typename ValueType,
         typename ...Remaining>
struct find_type<QueriedType, C<KeyType, ValueType>, Remaining...> : 
    find_type<QueriedType, KeyType, ValueType, Remaining...>{};

//entry point
template<typename ...>
struct entry_find_type;

template<typename QueriedType,
         typename ...Remaining>
struct entry_find_type<QueriedType, std::tuple<Remaining...>> :
    find_type<QueriedType, Remaining...> {};
编译器输出(gcc 4.9):

/tmp/gcc-explorer-compiler115628-35-8rkb3f/example.cpp:在“struct entry\u find\u type”的实例化中:
69:从这里开始需要
39:错误:“struct find_type,IFirstType,IDerived>”的类模板实例化不明确
结构项\u查找\u类型:
^
16:错误:候选项为:struct find_type
结构查找类型
^
30:错误:结构查找类型,剩余…>
结构查找类型:
^
39:错误:不完整类型“struct find_type,IFirstType,IDerived>”的使用无效
结构项\u查找\u类型:
^
5:错误:“struct find_type,IFirstType,IDerived>”的声明
结构find_type:std::false_type{};
^
/tmp/gcc-explorer-compiler115628-35-8rkb3f/example.cpp:在函数“int main(int,char**)”中:
69:错误:“value”不是“query\u type{aka entry\u find\u type,IFirstType,IDerived>}”的成员

static const bool bFound=查询类型::值//似乎有点奇怪,也许我误解了整个想法,但您似乎跳过了非包装专用化中的
ValueType
检查。这是一个正确的观察还是我误解了这个目标?对于
typedef std::tuple tuple\u type,当前代码返回的结果为
false
;typedef entry_find_type query_type
但是,元组中存在
ISecondType
。在第一个例子中,您最终得到了
find_type
,这恰好是明确的,因为在
对之后没有其他类型了。看起来有点奇怪,可能我误解了整个想法,但是您似乎跳过了非包装专门化中对
ValueType
的检查。这是一个正确的观察还是我误解了这个目标?对于
typedef std::tuple tuple\u type,当前代码返回的结果为
false
;typedef entry_find_type query_typeISecondType
。在第一种情况下,您将在
find_type
处结束,这恰好是明确的,因为
对之后没有其他类型。
class IFirstType
{
};

class ISecondType
{
};

class IDerived : public IFirstType, public ISecondType
{
};

int main(int argc, char*argv[])
{
  { //compiles fine
    typedef std::tuple<IFirstType, IDerived,
                       std::pair<ISecondType, IFirstType>>  tuple_type;
    typedef entry_find_type<ISecondType, tuple_type>        query_type;

    static const bool bFound = query_type::value;
  }

  { //compile error
    typedef std::tuple<std::pair<ISecondType, IFirstType>,
                       IFirstType, IDerived>                tuple_type;
    typedef entry_find_type<ISecondType, tuple_type>        query_type;

    //static const bool bFound = query_type::value; //<--- compiler error here
  }

  return 0;
}
/tmp/gcc-explorer-compiler115628-35-8rkb3f/example.cpp: In instantiation of 'struct entry_find_type<ISecondType, std::tuple<std::pair<ISecondType, IFirstType>, IFirstType, IDerived> >':
69 : required from here
39 : error: ambiguous class template instantiation for 'struct find_type, IFirstType, IDerived>'
struct entry_find_type<QueriedType, std::tuple<Remaining...>> :
^
16 : error: candidates are: struct find_type
struct find_type<QueriedType, KeyType, ValueType, Remaining...>
^
30 : error: struct find_type, Remaining ...>
struct find_type<QueriedType, C<KeyType, ValueType>, Remaining...> :
^
39 : error: invalid use of incomplete type 'struct find_type, IFirstType, IDerived>'
struct entry_find_type<QueriedType, std::tuple<Remaining...>> :
^
5 : error: declaration of 'struct find_type, IFirstType, IDerived>'
struct find_type : std::false_type {};
^
/tmp/gcc-explorer-compiler115628-35-8rkb3f/example.cpp: In function 'int main(int, char**)':
69 : error: 'value' is not a member of 'query_type {aka entry_find_type, IFirstType, IDerived> >}'
static const bool bFound = query_type::value; //<--- compiler error here
^
Compilation failed