【发布时间】:2018-07-15 20:24:57
【问题描述】:
另一个“在 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++ 和 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> 对象)调用它,我们得到(clang++ 和 g++)编译错误。
到目前为止,一切都很好。
问题出现在第三次调用
(&foo<int>)(bar<int, long>{}); // clang++ compiles; g++ gives error
我确信(也许我错了)相当于第二个(我们修复了Ts... 中的所有模板类型,然后我们用错误的参数调用函数)但是 g++ 似乎同意(并给出错误)clang++ 不同意(并且编译没有问题)。
和往常一样,问题是:谁是对的?
【问题讨论】:
-
VC++ 2017 不编译其中任何一个。
标签: c++ c++11 templates variadic-templates template-argument-deduction