另一个类型为“谁在g++和clang++之间正确的选择?”的问题适用于C++标准专家。
以下代码
template <int>
struct foo
{
template <typename>
friend void bar ()
{ }
};
int main ()
{
foo<0> f0;
foo<1> f1;
}
用clang++编译时没有问题(只有两个“未使用的变量”警告),但给出了以下错误
tmp_002-11,14,gcc,clang.cpp: In instantiation of ‘struct foo<1>’:
tmp_002-11,14,gcc,clang.cpp:27:12: required from here
tmp_002-11,14,gcc,clang.cpp:20:16: error: redefinition of ‘template<class> void bar()’
friend void bar ()
^~~
tmp_002-11,14,gcc,clang.cpp:20:16: note: ‘template<class> void bar()’ previously defined here
用g++编译。
与往常一样,问题是:谁是对的? g++还是clang++?
在我的Debian平台中使用clang++ 3.9.1和g++ 6.3.0进行了检查。但是,在Wandbox中进行尝试似乎与更新的版本相当。
最佳答案
在这种情况下,海湾合作委员会是正确的。
相关的标准措辞在[temp.inst]/2中:
与 friend 有关的部分由DR2174添加到了本段中,并在C++ 17中发布(这是缺陷报告,因此编译器也应将其应用于以前的标准版本)。
严格模式下的MSVC和EDG的最新版本也拒绝该代码,提示重新定义。
[temp.inject]/1在某种程度上是相关的,但是它只讨论 friend 功能,而不是 friend 功能模板: