C++11 模板功能参数包不在列表末尾
以下代码无法在g++和clang++上编译,并显示不同的错误消息。特别是,触发错误的是main的第二行 我不明白为什么,因为没有什么模棱两可的。该函数有两个参数,这意味着模板包必须正好有两个参数,并且所有类型都被正确地显式指定 有什么解释吗C++11 模板功能参数包不在列表末尾,c++11,templates,c++17,function-templates,C++11,Templates,C++17,Function Templates,以下代码无法在g++和clang++上编译,并显示不同的错误消息。特别是,触发错误的是main的第二行 我不明白为什么,因为没有什么模棱两可的。该函数有两个参数,这意味着模板包必须正好有两个参数,并且所有类型都被正确地显式指定 有什么解释吗 #include <iostream> enum A {A1,A2}; template <typename...Ts, A a=A2> void foo(Ts...ps) { (std::cout << ... <
#include <iostream>
enum A {A1,A2};
template <typename...Ts, A a=A2>
void foo(Ts...ps) { (std::cout << ... << ps); }
int main()
{
foo<int,int>(1,2); // this compiles
foo<int,int,A2>(1,2); // this does not compile
return 0;
}
可变模板参数是贪婪的,因此,如果尝试显式指定具有可变参数的模板的模板参数,一旦显式参数开始分配给可变数据包,所有剩余的参数都将分配给该数据包。在本例中,A2不是类型,因此当编译器尝试将其分配给Ts时。。。打包时,会导致错误 您可以重载模板,允许将枚举指定为第一个参数:
template <A a,typename...Ts >
void foo(Ts...ps) { std::cout << sizeof...(ps); }
template <typename...Ts>
void foo(Ts...ps) { foo<A2>(ps...); }
foo<int,int>(1,2); // this compiles
foo<A2,int,int>(1,2); // this compiles
替换显式模板参数发生在从函数参数推导任何内容之前。我不确定,如果我们试图想象改变这些规则来涵盖这一点,会出现什么奇怪的角落案例。这是一个很好的解决方案。非常感谢。