将模板参数依赖于参数列表

5

我已经定义了这个类

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 <int I>)? - bolov
你不能使用 template <typename T, T t> struct Foo; 吗? - Jarod42
2
最好的方法是展示您打算如何实例化Foo。 - bolov
@bolov:我不能展示给你看,因为我不能声明它...但是它的实例化有什么特别之处吗? - einpoklum
4个回答

2
您可以对结构进行部分特化:
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<Ts...>::inner_type的。


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

1
我能想到的最好答案是:

(原文未提供)

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

你需要明确地命名类型。


这是我一直在使用的解决方法。(实际上,在我的情况下,我不会费心使用静态断言,因为我将该值用作传递给需要 Bar<...>::inner_type 的函数的参数)。我可能最终会接受这个解决方案,但我不能点赞它,因为我不喜欢它... :-P - einpoklum

0

这解决了问题吗?

#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,"");
};

0

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

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

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

不,你没有。我需要将一个值作为模板参数传递,而不是类型。请参见被接受的答案。 - einpoklum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接