gpt4 book ai didi

c++ - Clang 与 GCC - Variadic 模板参数包后跟具有默认值的参数在 GCC 4.8 中有效,但在 Clang 3.5 中无效

转载 作者:可可西里 更新时间:2023-11-01 16:19:06 26 4
gpt4 key购买 nike

下面的代码适用于 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
}

它输出:

$ ./a.out
1
2
0
0

但是如果用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)
^

Clang 至少警告从 float 到 int 的隐式转换。好的,我们可以通过调用 func<float> 来更正它它将 float 参数放入模板包中。所以,如果我注释掉 func() , 它编译得很好。

我在标准中找不到任何明确说明可变参数模板包必须是参数声明子句中的最后一件事,只是它变成了一个非推导的上下文。

我的困惑来自于为什么 clang 不喜欢 func()什么时候func(1)是完全可以接受的。我可以手动定义 func(int optional = 4) { cout << optional << endl; }一切都很好(但是在传递 int 时我没有使用模板函数,我在 clang 和 gcc 中正确地得到了专门的 func()。什么是限制使用 func() 的 clang 强制?

最佳答案

这实际上被稍微错位的[temp.arg.explicit]/3覆盖了:

A trailing template parameter pack (14.5.3) not otherwise deduced will be deduced to an empty sequence of template arguments.

模板参数包在尾部,因此在除func<float>(3.3f) 之外的所有调用中都推导为空包。 ,也就是说,它们都是有效的(并且 Clang 可以很好地编译它们 as of 3.5 )。


但是,一旦我们将模板的声明调整为

,编译器就不再符合要求了
template <typename... Args, typename=void>
void func(Args... args, int optional = 0)

现在,上述引用不适用(因为 Args 不尾随)和 [temp.deduct.call]/1改为适用:

When a function parameter pack appears in a non-deduced context (14.8.2.5), the type of that parameter pack is never deduced.

(即这应该会导致推导失败。)

关于c++ - Clang 与 GCC - Variadic 模板参数包后跟具有默认值的参数在 GCC 4.8 中有效,但在 Clang 3.5 中无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27303283/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com