【问题标题】:Issue with variadic template template parameter pack与Variadic模板模板参数包的问题
【发布时间】:2021-09-15 01:45:53
【问题描述】:

考虑以下示例:

template< class A, int B, class C>
struct Obj {
A a_obj;
static constexpr int b_value = B;
C c_obj;

};

template< template<class... > class ... Templates >
struct Foo;


template<>
struct Foo<Obj> {

Obj<void*, 5, float> obj;
};


int main() {
Foo<Obj> foo;

};

这对我来说失败了(g++ 7.2,-std=c++17 出现以下错误:

templ.cpp:16:15: error: type/value mismatch at argument 1 in template parameter list for ‘template<template<class ...> class ... Templates> struct Foo’
   16 | struct Foo<Obj> {
      |               ^
templ.cpp:16:15: note:   expected a template of type ‘template<class ...> class ... Templates’, got ‘template<class A, int B, class C> struct Obj’
templ.cpp: In function ‘int main()’:
templ.cpp:23:8: error: type/value mismatch at argument 1 in template parameter list for ‘template<template<class ...> class ... Templates> struct Foo’
   23 | Foo<Obj> foo;
      |        ^
templ.cpp:23:8: note:   expected a template of type ‘template<class ...> class ... Templates’, got ‘template<class A, int B, class C> struct Obj’

它似乎没有得到匹配,虽然它看起来不像认为 template&lt;class ...&gt; class ... Templates 是语法错误,因此参数-参数包正在解析

这种类型的声明(有一些类型,一个常量值,然后是更多类型,或者最后可能是常量值)是否无法与可变参数模板模板包语法匹配?或者我没有正确使用语法

编辑

我修改了版本以避免在声明中使用非类型,但问题仍然存在:

template< template <class, class> class B, class A, class C>
struct Obj {
A a_obj;
//static constexpr int b_value = B;
B< C, A > b_obj;
C c_obj;

};

template< template<typename... > typename ... Templates >
struct Foo;

template<class A, class V>
struct Bar {
A a_obj;
//static constexpr int value = V;
V obj;
};

template<>
struct Foo<Obj> {

Obj<Bar, void*, float> obj;
};


int main() {
Foo<Obj> foo;

};

所以看起来不仅仅是非类型和类型不能在可变参数包上匹配,而是类型和模板的任何混合

我还尝试添加一个额外的可变参数包:

template< template<typename... > typename ... Templates, class ... Types >
struct Foo;

然后我得到:

error: parameter pack ‘template<class ...> class ... Templates’ must be at the end of the template parameter list
   12 | template< template<typename... > typename ... Templates, class ... Types >

【问题讨论】:

  • 您无法将类型和非类型的混合与可变参数包匹配。你需要像template&lt; template&lt;class,int,class &gt; class ... Templates &gt; 这样的东西。
  • 一个类模板也不能有两个参数包。

标签: c++ c++17 variadic-templates template-templates


【解决方案1】:

int B 是一个非类型模板参数。如果您希望 Obj 与特定的类模板一起使用,则必须将 Templates 声明为 template&lt;class, auto, class&gt; class,或者重新定义 Obj 以采用 std::integral_constant 以传递封装在类型中的值:

template<class A, class B, class C>
struct Obj {
    A a_obj;
    static constexpr int b_value = B::value;
    C c_obj;
};

template<template<class...> class... Templates>
struct Foo;

template<>
struct Foo<Obj> {
    Obj<void*, std::integral_constant<int, 5>, float> obj;
};

int main() {
    Foo<Obj> foo;
}

Try it on godbolt.org.

【讨论】:

  • 有趣。事实上,将非类型与类型混合似乎会破坏任何类型的可变参数包声明,无论它是否包含模板模板参数
  • @lurscher 有一个open proposal 来解决这样的场景
  • Patrick,我尝试通过删除所有提及的非类型来修改示例,只是在可变参数包中混合类型和模板,我得到了基本相同的错误
  • @lurscher,template &lt;class, class&gt; class B 不是类型,它是模板类型。 class 不适用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-13
  • 1970-01-01
  • 2021-09-05
  • 2013-08-27
  • 2012-11-05
  • 2014-03-15
相关资源
最近更新 更多