【问题标题】:How can I use template class inside of template class as a template template parameter with a template parameter?如何使用模板类内部的模板类作为带有模板参数的模板模板参数?
【发布时间】:2015-11-03 02:32:57
【问题描述】:

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

我写的内容类似于“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++ 标准阻止它。

感谢阅读。

【问题讨论】:

    标签: c++ templates c++11 stdtuple


    【解决方案1】:

    typename is_same_type_tt&lt; TypeLookingFor &gt;::type_tt

    type_tt 不是类型。上面你声称它是。您的谎言使编译器感到困惑,使其认为它与 template&lt;class&gt;class 参数不匹配。

    试试is_same_type_tt&lt; TypeLookingFor &gt;::template type_tt

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

    【讨论】:

    • 谢谢!它似乎正在工作。但是为了更好的讨论,我把“typename”放在“is_same_type_tt”。据我所知,在模板类上使用模板参数时,它应该带有“typename”。例如,vector 一直都可以,但是 type 来自模板参数的 vector 应该有“typename”。我相信我尝试过“typename is_same_type_tt::template type_tt”,但它没有用。我不知道为什么在这种情况下我不应该有“typename”关键字。
    • @JaeHyukKwak 不;只有依赖类型才需要 typename。 is_same_type_tt 的模板实例必须产生一个类型,所以 is_same_type_tt&lt; blah &gt; 是一个类型。依赖类型::something 可以是值(枚举标记、静态等)、类型或模板。使用typename 表示它是一个类型。
    猜你喜欢
    • 1970-01-01
    • 2011-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多