我想知道为什么以下代码无法编译:
struct S
{
template <typename... T>
S(T..., int);
};
S c{0, 0};
此代码无法同时使用 clang 和 GCC 4.8 进行编译。这是 clang 的错误:
test.cpp:7:3: error: no matching constructor for initialization of 'S'
S c{0, 0};
^~~~~~~
test.cpp:4:5: note: candidate constructor not viable: requires 1 argument, but 2 were provided
S(T..., int);
^
在我看来,这应该可行,并且 T 应该被推导为长度为 1 的包。
如果标准禁止这样做,有人知道为什么吗?
最佳答案
因为当函数参数包不是最后一个参数时,模板参数包无法从中推导出来,模板参数推导将忽略它。
因此将两个参数 0, 0
与 , int
进行比较,结果不匹配。
像这样的推导规则需要涵盖许多特殊情况(比如当两个参数包彼此相邻时会发生什么)。由于参数包是 C++11 中的一项新功能,因此相应提案的作者保守地起草了规则。
请注意,如果不以其他方式推导,则尾随模板参数包将为空。所以当你用一个参数调用构造函数时,事情就会起作用(注意这里模板参数包和函数参数包的区别。前者是尾随的,后者不是)。
关于c++ - 包扩展不在最后一个参数中的可变参数函数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40507747/