【问题标题】:Having a template parameter depend on a parameter list具有模板参数取决于参数列表
【发布时间】:2016-06-16 05:17:34
【问题描述】:

我已经定义了类

template <typename... Ts> struct Bar {
   using inner_type = /* whatever */;
};

现在,我需要定义一个模板类Foo,其模板参数是某个参数包,并为该参数包实例化一个Bar::inner_type 类型的值。不幸的是,我似乎无法做到。如果我这样定义:

template <Bar<Ts...>::inner_type SomeValue, typename... Ts> struct Foo { };

编译器在使用时无法识别Ts,因为它还没有看到参数包;但如果我这样定义:

template <typename... Ts, Bar<Ts...>::inner_type SomeValue> struct Foo { };

编译器嘲笑我尝试在其他模板参数之前使用参数包。

那么我该怎么做呢?

注意:如果重要的话,这对我来说在 GCC 4.9.3 中失败了。

【问题讨论】:

  • 非类型模板参数(例如template &lt;int I&gt;)?
  • 你不能用template &lt;typename T, T t&gt; struct Foo;吗?
  • 最好的办法是向我们展示您打算如何实例化 Foo
  • @bolov:我不能给你看,因为我不能声明它......但它的实例化有什么特别之处?

标签: c++ c++11 variadic-templates using


【解决方案1】:

您可以部分专门化您的结构:

template<typename...>
struct Bar { using inner_type = int; };

template <typename T, typename T::inner_type T>
struct Foo;

template <typename... Ts, typename Bar<Ts...>::inner_type SomeValue>
struct Foo<Bar<Ts...>, SomeValue> { };

int main() {
    Foo<Bar<int>, 3> foo;
}

这样推导出Ts 参数包,Foo 期望第二个模板参数的类型为Bar&lt;Ts...&gt;::inner_type

【讨论】:

  • 这不应该编译...它在另一个模板参数之前有一个参数包。
  • @einpoklum 它是在专业化中推断出来的,它是合法的。它确实可以编译。 :-)
【解决方案2】:

我能想到的最好的东西:

template <class Inner, Inner Val, class... Args>
struct Foo {
  static_assert(std::is_same<Inner, typename Bar<Args...>::inner_type>::value, "Wrong type");
};

您需要明确命名类型。

【讨论】:

  • 这是我一直在做的一种解决方法。 (实际上,在我的情况下,我不关心静态断言,因为我使用该值作为需要Bar&lt;...&gt;::inner_type 的函数的参数)。我可能最终会接受这个,但我不能投票,因为我不喜欢它...... :-P
【解决方案3】:

这能解决问题吗?

#include <type_traits>

using namespace std;

template <typename... Ts> class Bar {
 public:
    using inner_type = int;
};

template <typename... Ts> class Foo {
  using bar_inner_type = typename Bar<Ts...>::inner_type;
  static_assert(is_same<int, bar_inner_type>::value,"");
};

【讨论】:

    【解决方案4】:

    如果我正确理解了您的问题,您可以这样做:

    template <typename... Ts> struct Bar {
       using inner_type = /* whatever */;
    };
    
    template <typename... Ts> struct Foo {
       using inner_type = typename Bar<Ts...>::inner_type;
    };
    

    【讨论】:

    • 不,你没有。我需要传递一个值作为模板参数,而不是类型。查看接受的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 2017-02-22
    • 1970-01-01
    相关资源
    最近更新 更多