简体   繁体   English

g ++和clang ++在模板类中定义的朋友模板函数的不同行为

[英]g++ and clang++ different behaviour with friend template function defined inside a template class

Another question of type "who's right between g++ and clang++?" 另一个问题是“g ++和clang ++之间谁是对的?” for C++ standard gurus. 对于C ++标准大师。

The following code 以下代码

template <int>
struct foo
 {
   template <typename>
   friend void bar ()
    { }
 };

int main ()
 {    
   foo<0>  f0;
   foo<1>  f1;
 }

compile without problem with clang++ (only two "unused variable" warnings) but give a the following error 使用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

compiling with g++. 用g ++编译。

The question, as usual, is: who's right ? 像往常一样,问题是:谁是对的? g++ or clang++ ? g ++或clang ++?

Checked with clang++ 3.9.1 and g++ 6.3.0 in my Debian platform. 在我的Debian平台上查看了clang ++ 3.9.1和g ++ 6.3.0。 But, trying in Wandbox, seems equals with more recent versions. 但是,尝试使用Wandbox,似乎与更新的版本相同。

GCC is right in this case. GCC在这种情况下是对的。

The relevant standard wording is in [temp.inst]/2 : 相关的标准措辞在[temp.inst] / 2中

The implicit instantiation of a class template specialization causes 类模板特化的隐式实例化导致
— the implicit instantiation of the declarations, but not of the definitions, of the non-deleted class member functions, member classes, scoped member enumerations, static data members, member templates, and friends; - 未删除的类成员函数,成员类,作用域成员枚举,静态数据成员,成员模板和朋友的声明的隐式实例化,但不是定义的隐式实例化; and
[...] [...]
However, for the purpose of determining whether an instantiated redeclaration is valid according to 6.2 and 12.2, a declaration that corresponds to a definition in the template is considered to be a definition. 但是,为了根据6.2和12.2确定实例化的重新声明是否有效,与模板中的定义相对应的声明被认为是定义。 [ Example: [...] [ 例如: [...]

 template<typename T> struct Friendly { template<typename U> friend int f(U) { return sizeof(T); } }; Friendly<char> fc; Friendly<float> ff; // ill-formed: produces second definition of f(U) 

— end example ] - 结束例子 ]

The parts related to friends were added to this paragraph by DR2174 and published in C++17 (it's a defect report, so compilers should apply it to previous standard versions as well). 与朋友相关的部分由DR2174添加到本段并在C ++ 17中发布(这是一个缺陷报告,因此编译器也应该将它应用于以前的标准版本)。


Recent versions of MSVC and EDG in strict mode also reject the code, complaining about a redefinition. 最新版本的MSVC和EDG在严格模式下也拒绝代码,抱怨重新定义。

[temp.inject]/1 is somewhat related, but it only talks about friend functions, not friend function templates: [temp.inject] / 1有点相关,但它只谈到朋友的功能,而不是朋友的功能模板:

Friend classes or functions can be declared within a class template. 可以在类模板中声明好友类或函数。 When a template is instantiated, the names of its friends are treated as if the specialization had been explicitly declared at its point of instantiation. 实例化模板时,会将其朋友的名称视为在实例化时明确声明了特化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在类中定义的友元函数模板是否可用于查找? clang ++和g ++不同意 - Is a friend function template defined in the class available for lookup? clang++ and g++ disagree g ++和clang ++使用变量模板和SFINAE的不同行为 - g++ and clang++ different behaviour with variable template and SFINAE g ++和clang ++使用指向可变参数模板函数的指针的不同行为 - g++ and clang++ different behaviour with pointer to variadic template functions g ++和clang ++使用自动参数的模板特化的不同行为 - g++ and clang++ different behaviour with template specialization for auto argument 带有集成模板参数的g ++和clang ++不同的行为 - g++ and clang++ different behaviour with integral template parameter g ++和clang ++不同的行为推断函数的模板返回类型 - g++ and clang++ different behaviour inferring the template return type of a function C ++朋友函数模板重载和SFINAE在clang ++,g ++,vc ++中的不同行为(C ++ 14模式) - C++ friend function template overloading and SFINAE different behaviors in clang++, g++, vc++ (C++14 mode) g ++和clang ++不同的行为推导可变参数模板`auto`值 - g++ and clang++ different behaviour deducing variadic template `auto` values 编译模板类因g ++或clang ++失败 - Compile template class failed by g++ or clang++ g ++和clang ++使用静态成员的递归初始化的不同行为 - g++ and clang++ different behaviour with recursive initialization of a static member
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM