C++11/14/17,GCC 7 与 GCC 8:好友类模板的名称查找
C++11/14/17, GCC 7 vs GCC 8: Name lookup for friend class templates
我试图弄清楚以下代码在GCC 7中有效,但在GCC 8.1中无效。
代码的作用是:
- 定义(并转发声明(类模板
MyGoodFriend
(在全局命名空间中( - 定义
inner
命名空间内Befriended
类模板 - 让
MyGoodFriend
的所有专业成为Befriended
的朋友
有问题的一块是
template<class FA>
friend class MyGoodFriend;
我明白问题是什么。GCC 8.1 要求我在friend
声明中使用完全限定的名称::MyGoodFriend
- 但是,GCC 7 只对MyGoodFriend
感到满意。这是代码:
template<class A>
class MyGoodFriend;
namespace inner {
template<class T>
class Befriended {
private:
int i;
T t;
template<class FA>
friend class MyGoodFriend;
// This works for gcc 8.1:
// template<class FA>
//friend class ::MyGoodFriend;
};
} // namespace inner
template<class A>
class MyGoodFriend {
public:
void do_something() {
inner::Befriended<bool> bf;
bf.i = 42;
}
};
int main() {
MyGoodFriend<int> mgf;
mgf.do_something();
}
您可以在此处使用 GCC 7 与 8 进行测试:https://godbolt.org/g/6u9rgy
两个问题:
为什么海湾合作委员会的行为发生了变化?
GCC 7是否误解了标准?或者这是 GCC 8 中的一个错误?
如果GCC 8是正确的:为什么?
如果我正确阅读了标准(请参阅此处的 C++14 标准(: 第 3.4 节(指定名称查找的工作原理(,第 7.4 点指出:
定义 X 类中使用的名称 [...]
- 如果 X 是命名空间 N 的成员,或者是 是 N 的成员,或者是本地类或本地中的嵌套类 作为 N 成员的函数的类,在定义之前 命名空间 N 中的类 X 或 N 的封闭命名空间之一
显然,MyGoodFriend
是在封闭命名空间中声明的,因此它应该在Befriended
中可见 - 对吧?
感谢您的任何帮助!
来自 [namespace.memdef]/3,强调我的(C++11 中的措辞相同(:
如果非本地类中的友元声明首先声明类、函数、类模板或函数模板99,则该友元是最内层封闭命名空间的成员。[...]如果友元声明中的名称既不是限定的也不是模板 ID,并且声明是一个函数或详细类型说明符,则用于确定实体是否已先前声明的查找不应考虑最内层封闭命名空间之外的任何范围。
也就是说,当您编写:
template<class FA>
friend class MyGoodFriend;
我们只寻找inner::MyGoodFriend
,而不是::MyGoodFriend
。由于我们找不到它,我们认为它是类模板inner::MyGoodFriend
的前向声明。因此,::MyGoodFriend
不是friend
编辑。
随着修订版,gcc 7 的编译可能是因为许多与模板访问相关的错误之一。看到这个元错误。GCC 8的行为是正确的。
- 正在查找文档以获得PS4平台的C++中的设备信息
- 在C++中查找文件
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 模板元程序查找相似的连续类型名称
- 在UNIX系统中使用DIR查找文件的字节大小
- 奇怪的结构&GCC&clang(void*返回类型)
- GCC本机矩阵运算库
- PowerPC ppc64le上的Gcc Woverloaded虚拟错误
- 使用gcc从静态链接的文件中查找可选符号
- C++使用旧编译器GCC 4.4.0在结构列表中查找字符串
- C++11/14/17,GCC 7 与 GCC 8:好友类模板的名称查找
- 在哪里查找 GCC 实现定义行为的实现?
- 如何强制 gcc 查找自己的 c++ 头文件,而不覆盖 CXX 变量
- 性能映射 C++ 查找(G++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3))
- clang与gcc在查找声明方面有何不同
- GCC—gc-sections和查找符号依赖项
- GCC、Clang和IBM在如何执行依赖模板参数的名称查找方面存在分歧.哪一个是对的
- Clang和GCC在执行限定名称查找时的不同行为
- Visual Studio 10 和 GCC 4.5 之间的哪个编译器在运算符重载和参数相关查找方面是正确的
- 如何查找已安装的MinGW GCC编译器的PATH变量