为什么我需要在命名空间中包含此友元函数的定义?(Why do I need to enclose the definition of this friend function in a namespa

编程入门 行业动态 更新时间:2024-10-15 12:34:14
为什么我需要在命名空间中包含此友元函数的定义?(Why do I need to enclose the definition of this friend function in a namespace? [duplicate])

这个问题在这里已有答案:

名称空间内的朋友函数声明/定义 2答案

给定一个名为N的名称空间N和头文件中的友元函数f :

namespace N { class C { friend void f(); } }

如果我在cpp文件中定义友元函数f ,如下所示:

void N::f() { ... }

它没有编译。 如果我这样定义:

namespace N { void f() { ... } }

确实编译 。 为什么?

我正在使用gcc 4.4,但我在Coliru编译C ++ 14时尝试了类似的例子,并得到了相同的行为

This question already has an answer here:

Friend function declaration/definition inside a namespace 2 answers

Given a namespace N with a class C and a friend function f in a header file:

namespace N { class C { friend void f(); } }

If I define the friend function f in the cpp file like this:

void N::f() { ... }

it does not compile. If I define it like this:

namespace N { void f() { ... } }

it does compile. Why?

I'm using gcc 4.4, but I tried a similar example in Coliru compiling for C++14 and got the same behavior

最满意答案

从GCC 4.7到现在的7.0时代,GCC没有在封闭的命名空间中引入新名称,如下所述:

basic.scope.pdecl / 11

Friend声明引用的函数或类是最近的封闭命名空间的成员,但它们不会在该命名空间中引入新名称。

虽然, GCC提供了一个兼容性开关( -ffriend-injection将名称注入封闭的命名空间)。 但是,从clang 3.1到4.0, clang将声明注入封闭的命名空间。

虽然可以通过ADL找到这样的函数: namespace.memdef / 3

如果调用了友元函数或函数模板,则可以通过名称查找找到其名称,该名称查找考虑名称空间中的函数和与函数参数类型相关联的类( basic.lookup.argdep )。


看到这个相关的问题 ,那么,所有编译器应该尊重的是:

namespace N { class C { friend void f(); }; void f(); //introduce the name } void N::f() //define it { ... }

看到Live On Coliru

或者另一种方式:

namespace N { class C{ friend void f(); }; } namespace N { void f() { ... } }

Right from the days of GCC 4.7 all up to now 7.0, GCC doesn't introduce a new name into the enclosing namespace as described by:

basic.scope.pdecl/11

Friend declarations refer to functions or classes that are members of the nearest enclosing namespace, but they do not introduce new names into that namespace.

Although, GCC provides a compatibility switch (-ffriend-injection to inject the name into the enclosing namespace). However, right from clang 3.1 to 4.0, clang injects the declaration into the enclosing namespace.

Although such function can be found via ADL: namespace.memdef/3

If a friend function or function template is called, its name may be found by the name lookup that considers functions from namespaces and classes associated with the types of the function arguments (basic.lookup.argdep).


See this related question, So, what all the compilers should honor is:

namespace N { class C { friend void f(); }; void f(); //introduce the name } void N::f() //define it { ... }

See it Live On Coliru

Or the other way:

namespace N { class C{ friend void f(); }; } namespace N { void f() { ... } }

更多推荐

本文发布于:2023-07-15 07:11:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1111369.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:函数   定义   空间   enclose   definition

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!