Ale*_*lex 15 c++ templates variadic-templates
我正在使用此处列出的书籍学习 C++ 。我特别读到了有关可变参数模板的内容。现在,为了进一步阐明我的概念,我还编写了简单的示例,并尝试使用调试器和 cout 语句自己理解它们。
下面给出了一个用 gcc 编译但被 clang 拒绝的程序。演示。
template<typename T, typename... V>
struct C
{
T v(V()...);;
};
int main()
{
C<int> c; //works with gcc but rejected in clang
C<int, double, int, int> c2; //same here: works with gcc but rejected in clang
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是哪个编译器就在这里(如果有的话)?
这是 clang 给出的错误:
<source>:6:12: error: '...' must be innermost component of anonymous pack declaration
T v(V()...);;
^~~
...
1 error generated.
Compiler returned: 1
Run Code Online (Sandbox Code Playgroud)
Hol*_*Cat 10
这是一个海湾合作委员会错误。正确的语法是T v(V...());,Clang 接受而 GCC 拒绝(错误)。
在函数参数列表中,...展开包的 必须位于参数名称之前,或者位于名称原本所在的位置。这种情况在类似的情况下更常见V &&... v。
相关语法为:函数定义->声明符->参数和限定符-> ... ->参数声明->抽象声明符(“抽象”=无参数名称)。
[dcl.fct]/26表示如果函数参数列表中存在歧义,无论...是包扩展还是 C 样式可变参数,它都会解析为包扩展。但在这种情况下,没有歧义,V()...使包不展开(这应该是编译错误)并且...应该是 C 风格的可变参数。
GCC 在接受程序时是错误的,因为函数参数包是...在函数参数名称之前(或代替)使用省略号 ( ) 引入的。
这意味着在您的示例中,声明具有函数指针类型参数的函数的正确方法是T v(V...());。但请注意,gcc 拒绝此修改后的代码。演示
这是 gcc 错误报告:
有趣的是,gcc 拒绝T v(V...())但接受T v(V...b())。演示
template<typename T, typename... V>
struct C
{
//-------vvv---------->this is the correct way which gcc rejects
T v(V...());
//-------vvv---------->but gcc accepts this when we name the parameter
T v(V...b());
};
Run Code Online (Sandbox Code Playgroud)