2015-11-03 111 views
1

我正在尝试使用模板类作为模板参数与另一个模板参数。听起来,它非常复杂/扭曲,我无法弄清楚如何修复编译器错误。如何使用模板类中的模板类作为模板参数的模板参数?

我写的是像“std :: find_if”,但它适用于“std :: tuple”。如下所示的代码,它似乎是工作,当我指定is_same_type_tt类型,但是当我尝试使用模板参数与is_same_type_tt,编译器会抱怨:

main.cpp:75:13: error: type/value mismatch at argument 2 in template parameter list for 'template<class TupleType, template<class> class Action> struct tuple_find_if_tt' 
     >::value; 
    ^

的源代码是这样的:

template< typename TypeLookingFor > 
struct is_same_type_tt 
{ 
    typedef TypeLookingFor type_looking_for; 
    template< typename TypeCompareTo > 
    struct type_tt : is_same< type_looking_for, TypeCompareTo > 
    {}; 
}; 

// base for the recusion 
template< 
    typename TupleType 
    , size_t Index 
    , template<typename> class Action > 
struct tuple_find_if_recur_tt; 

// last in the recursion 
template< 
    typename TupleLast 
    , size_t Index 
    , template<typename> class Action > 
struct tuple_find_if_recur_tt< tuple<TupleLast>, Index, Action > 
    : conditional< 
     Action<TupleLast>::value 
     , integral_constant< size_t, Index > 
     , integral_constant< size_t, -1 > >::type 
{}; 

// recursion 
template< 
    typename TupleHead, typename... TupleRest 
    , size_t Index 
    , template<typename> class Action > 
struct tuple_find_if_recur_tt< 
    tuple< TupleHead, TupleRest... >, Index, Action > 
    : conditional< 
     Action<TupleHead>::value 
     , integral_constant< size_t, Index > 
     , tuple_find_if_recur_tt< 
      tuple<TupleRest...> 
      , Index + 1u 
      , Action > >::type 
{}; 

// wrap the recursion 
template< 
    typename TupleType 
    , template<typename> class Action > 
struct tuple_find_if_tt 
    : tuple_find_if_recur_tt< TupleType, 0u, Action > 
{}; 

作为测试,下面的代码编译好:

// this works fine. 
static_assert(
    tuple_find_if_tt< tuple< int, float, double > 
    , is_same_type_tt<float>::type_tt >::value == 1, ""); 

但是当我尝试用一​​个更模板参数使用它,它不工作:

// problem starts from here... 
template< typename... Types > 
struct tuple_indirect_find_tt 
{ 
    typedef tuple<Types...> tuple_type; 
    // tuple_type obj_; 

    template< typename TypeLookingFor > 
    static constexpr size_t find() 
    { 
     return tuple_find_if_tt< 
      tuple_type 
      // something is not right below... 
      , typename is_same_type_tt<TypeLookingFor>::type_tt 
      >::value; 
    } 
}; 

// this doesn't work. 
static_assert(
    tuple_indirect_find_tt< int, float, double >::find<float>() 
    == 1, ""); 

为了得到它的工作,我不得不重构模板类,这样我可以这样做:

return tuple_find_if_tt< 
    tuple_type 
    , is_same_type_tt 
    , typename TypeLookingFor // this is separated from is_same_type_tt 
    >::value; 

解决方法似乎并没有太糟糕,但我仍想知道什么我做错了。 如果这不是一个可行的方法,我想知道C++标准是什么阻止它。

感谢您的阅读。

回答

3

typename is_same_type_tt<TypeLookingFor>::type_tt

type_tt不是一个类型。上面你声称是。你的谎言会让编译器感到困惑,使其认为它不符合template<class>class参数。

尝试is_same_type_tt<TypeLookingFor>::template type_tt

这里我们说,从属名称type_tttemplate,而不是typename

+0

谢谢!它似乎在工作。但为了更好的讨论,我把“typename”设置为“is_same_type_tt ”。据我所知,当在模板类上使用模板参数时,它应该在“typename”之前。例如,矢量< float >始终处于良好状态,但矢量< Type >其中来自模板参数的类型应具有“typename”。我相信我尝试过“typename is_same_type_tt :: template type_tt”,但它不起作用。我不知道为什么我不应该在这种情况下有“typename”关键字。 –

+0

@JaeHyukKwak no; typename仅用于依赖类型。 'is_same_type_tt'的模板实例必须产生一个类型,所以'is_same_type_tt < blah >'是一个类型。依赖类型':: something'可以是一个值(枚举标记,静态等),类型或模板。 'typename'的使用说它是一种类型。 – Yakk

相关问题