[英]g++ and clang++ different behaviour with pointer to variadic template functions
另一个“g ++和clang ++之间谁是正确的?” C ++标准大师的问题。
代码如下
template <typename ...>
struct bar
{ };
template <typename ... Ts>
void foo (bar<Ts...> const &)
{ }
int main ()
{
foo<int>(bar<int, long>{}); // g++ and clang++ compile
(*(&foo<int>))(bar<int, long>{}); // g++ and clang++ give error
(&foo<int>)(bar<int, long>{}); // clang++ compiles; g++ gives error
}
模板函数foo()
接收可变参数模板参数bar
。
第一个电话
foo<int>(bar<int, long>{}); // g++ and clang++ compile
适用于clang ++ ang g ++。
如果我理解正确,与foo<int>
是阐明只有第一个模板参数,这不完全名单Ts...
参数。 因此编译器会查看参数( bar<int, long>
对象)并推导出完整列表。
第二个电话是不同的
(*(&foo<int>))(bar<int, long>{}); // g++ and clang++ give error
如果我理解正确,使用(&foo<int>)
我们得到指向foo
实例化的指针,其中Ts...
正好是int
(不仅是列表的第一种类型而是整个列表)并且取消引用它( *(&foo<int>)
)并使用错误的参数( bar<int, long>
object)调用它,我们得到(clang ++和g ++)编译错误。
到现在为止还挺好。
问题出现在第三次电话会议上
(&foo<int>)(bar<int, long>{}); // clang++ compiles; g++ gives error
我确信(也许我错了)等同于第二个(我们在Ts...
修复所有模板类型,然后我们用错误的参数调用函数)但g ++似乎同意(并给出错误)clang ++不同意(和编译没有问题)。
像往常一样,问题是:谁是对的?
让我们来看一个更简单的案例:
template <class A, class B>void foo(B) {};
int main()
{
(&foo<char>)(1);
}
clang ++编译这个,而g ++失败并带有以下消息:
错误:没有上下文类型信息的重载函数的地址
例如,该程序给出了相同的消息:
void moo(int) {};
void moo(int*){};
int main()
{
&moo != nullptr;
}
显然,目的是引用[over.over],它讨论了获取重载函数的地址。 标准中的这个位置指定在什么上下文中可以使用重载的函数名称(赋值的RHS,函数调用中的参数等)。 然而它说
如果没有参数 ,则不应在除列出的上下文之外的上下文中使用重载的函数名称。 (强调我的)
现在, foo
in (&foo<char>)(1)
没有参数 ? g ++似乎沉沦了。 然而它很乐意编译
(&moo)(1);
从第二个例子。 所以我们在这里至少有一些不一致。 采用相同的规则来控制函数模板和重载集的地址,因此(&foo<char>)(1)
和(&moo)(1)
应该既有效又无效。 标准本身似乎表明嘿应该都是有效的:
重载函数名称可以在&运算符[...]之前[ 注意 :忽略重载函数名称周围的任何多余括号(5.1)。 - 结束说明 ]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.