可变参数模板模板参数包的问题
Issue with variadic template template parameter pack
考虑以下示例:
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<class ...> 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 >
int B
是非类型模板参数。如果您希望它与特定的 class 模板一起使用,则必须将 Templates
声明为 template<class, auto, class> 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;
}
考虑以下示例:
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<class ...> 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 >
int B
是非类型模板参数。如果您希望它与特定的 class 模板一起使用,则必须将 Templates
声明为 template<class, auto, class> 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;
}