ile*_*ron 10 c++ clang variadic-templates c++11
以下代码适用于gcc-4.8.2
#include <iostream>
using namespace std;
template<typename... Args>
void func(Args... args, int optional = 0)
{
cout << optional << endl;
}
int main()
{
func(1);
func(2.1f); // converts 2.1 to int as 'optional' parameter
func<float>(3.3f); // Fine, prints '0'
func(); // gcc OK, fails to compile with clang-3.5
}
Run Code Online (Sandbox Code Playgroud)
它输出:
$ ./a.out
1
2
0
0
Run Code Online (Sandbox Code Playgroud)
但是如果用clang-3.5编译失败,
test_variadic.cpp:15:2: error: no matching function for call to 'func'
func();
^~~~
test_variadic.cpp:5:6: note: candidate function template not viable: requires at least argument 'args', but no arguments were provided
void func(Args... args, int optional = 0)
^
Run Code Online (Sandbox Code Playgroud)
Clang至少警告从float到int的隐式转换.好的,我们可以通过调用func<float>将float参数放入模板包来纠正它.所以,如果我发表评论func(),它编译得很好.
我无法在标准中找到任何明确说明variadic模板包必须是参数声明子句中的最后一件事,只是它变成了非推导的上下文.
我的困惑来自于为什么clang不喜欢func()何时func(1)完全可以接受.我可以手动定义func(int optional = 4) { cout << optional << endl; }并且一切都很好(但是在传递时int我没有使用模板化函数而是正确地获得了func()clang和gcc中的特殊功能.什么是clang强制执行限制使用func()?
这实际上被稍微错位的[temp.arg.explicit]/3所覆盖:
未以其他方式推导的尾随模板参数包 (14.5.3) 将被推导为模板参数的空序列。
模板参数 pack 是尾随的,因此在除 之外的所有调用中都推导为空包func<float>(3.3f),也就是说,它们都是有效的(并且从 3.5 开始, Clang 可以很好地编译它们)。
然而,一旦我们将模板的声明调整为
template <typename... Args, typename=void>
void func(Args... args, int optional = 0)
Run Code Online (Sandbox Code Playgroud)
现在,上述引用不适用(因为Args不是尾随)并且[temp.deduct.call]/1适用:
当函数参数包出现在非推导上下文 (14.8.2.5) 中时,永远不会推导该参数包的类型。
(也就是说,这应该会导致演绎失败。)
| 归档时间: |
|
| 查看次数: |
777 次 |
| 最近记录: |