c++ - 包扩展不在最后一个参数中的可变参数函数模板

标签 c++ templates c++11 variadic-templates function-templates

我想知道为什么以下代码无法编译:

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/

相关文章:

使用模板的 C++ 11 异步编程

c++ - 如何在 Boost Graph Library 中进行 BFS 时修改属性?

c++ - 调用删除时出现段错误

c++ - 在 C++ 中重命名(别名/转发)函数的最佳方法是什么?

c++ - 从文件中获取特定的 c++ 函数而不包含文件

c++ - 源文件中的非类型模板参数显式实例化

具有模板和可见性的 c++ 继承

c++ - 模板作为类中的参数

C++ 11使可变参数构造函数理解初始化列表的初始化列表

c++ - 复制构造函数和转发构造函数之间的冲突