为什么我需要将此朋友函数的定义包装在名称空间中
Why do I need to enclose the definition of this friend function in a namespace?
在标题文件中给定一个名称空间N
和类C
和朋友函数f
:
namespace N
{
class C
{
friend void f();
}
}
如果我在CPP文件中定义了朋友函数f
:
void N::f()
{
...
}
它不编译。如果我这样定义它:
namespace N
{
void f()
{
...
}
}
it do compile 。为什么?
我正在使用GCC 4.4,但是我在Coliru中尝试了一个类似的示例,用于C 14,并获得了相同的行为
从GCC 4.7的日子到现在为7.0的日子,GCC不会在封闭名称空间中引入新名称:
basic.scope.pdecl/11
朋友声明是指函数或类 最近的封闭名称空间,但它们不引入新名称 进入该名称空间。
虽然, 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
{ ... }
看到它活在coliru
上或另一种方式:
namespace N
{
class C{
friend void f();
};
}
namespace N
{
void f()
{ ... }
}
如果符号在其定义之前在命名空间N
内声明,则作为合格名称的定义应效果很好。否则它不起作用。
以下对于视觉工作室是正确的。
好:
namespace N
{
void f();
}
void N::f() { }
不是真的可以,但是在Visual Studio中工作:
namespace N
{
class C
{
friend void f();
}
}
void N::f() { }
不正常:
void N::f() { } // error, undefined N
不正常:
namespace N
{
}
void N::f() { } // error, f is not a member of N
,但我现在无法在不同的编译器上测试。
相关文章:
- 创建包装升压适配器的自定义范围类
- 自定义引用包装器的常量正确性
- libfreenect c++包装中未定义的引用
- 在 stl 容器包装器中定义迭代器类型
- C++,当函子不是一个选项时,我如何编写带有自定义函数调用的模板化 RAII 包装器?
- Objective-C C++ 包装器 类型错误的不完整定义
- 将自定义代码添加到Swig包装器中
- 通过Overloading Operator []访问自定义数组包装器中的元素
- “无法将函数定义与现有声明匹配”,当包装在 std::vector 中时
- 编写安全包装类以管理用户定义对象的指针
- 提升 Python 导入失败,未定义包装类的符号
- 无法包装标题文件中定义的简单类
- 为什么我需要将此朋友函数的定义包装在名称空间中
- 在 c++ 中包装来自不同库的自定义类型
- 为包装列表自定义迭代器
- 从Rcpp中的包装方法返回自定义对象
- 用 boost::graph 包装我的自定义图形并计算dijkstra_shortest_paths
- 性能:基元类型的类型定义与包装类
- 将 std::unique_ptr 与自定义分配器一起使用,以包装原始指针
- OpenCL 1.1 使用C++包装器的未定义引用