我偶然发现了一个错误,它只出现在GCC 6.2.0上,而不是出现在Clang 3.9.0上(都在-std=c++14
模式下).我不确定哪种行为是正确的(以及我是否应该提交错误).
这是代码:
template<typename type_t>
class foo_t
{
};
class bar_t
{
public:
using foo_t = int;
};
class baz_t:
public bar_t
{
private:
template<typename type_t>
friend class foo_t;
};
Run Code Online (Sandbox Code Playgroud)
在GCC上,这会出现以下错误:
test.cpp:17:15: error: using typedef-name ‘using foo_t = int’ after ‘class’
friend class foo_t;
^~~~~
test.cpp:9:19: note: ‘using foo_t = int’ has a previous declaration here
using foo_t = int;
^
Run Code Online (Sandbox Code Playgroud)
根据我所知的C++标准,父级typedef
(或using
s)不应泄漏到子级的范围内,您需要明确限定名称:例如,请参阅将"typedef"从基于"模板"的派生类传播到"模板".所以在我看来,GCC在这里是不正确的,但我不太确定我的C++知识可以自信地说.
谢谢你的帮助!
根据我对 C++ 标准的了解,父级
typedef
(或using
父级)不应泄漏到子级的范围中,并且您需要显式限定名称
这是不正确的。基类中声明的成员(包括类型别名)通常在派生类中可见。您链接到的问题专门涉及具有依赖基类的模板,其中适用两阶段名称查找(同样,适用于所有内容,而不仅仅是类型别名)。
除此之外,标准的相关部分是 C++14 (N4140) [dcl.type.elab] 7.1.6.3/2 (强调我的):
3.4.4 描述了如何对详细类型说明符中的标识符进行名称查找。如果标识符 解析为类名或枚举名,则详细类型说明符将其引入声明中,就像简单类型说明符引入其类型名一样。如果标识符解析为typedef-name或simple-template-id解析为别名模板特化,则详细类型说明符格式错误。
(注意:详细类型说明符是我们正在处理的class T
某些类型的构造)。T
3.4.4 反过来说,当将详细类型说明符中的标识符解析为名称时,非类型名称将被忽略(但通常会找到类型名称)。
foo_t
因此,GCC 实际上是正确的,因为作用域中的typedef-namebar_t
比全局作用域 template-name 的作用域“更接近” foo_t
。foo_t
因此,内部的非限定名称baz_t
解析为bar_t::foo_t
,它是一个typedef 名称,因此使得详细类型说明符格式错误。
问题在于不合格名称的解析foo_t
。正如您在问题评论中指出的那样,明确说明foo_t
您的意思应该解决问题:
tempalte <typename type_t>
friend class ::foo_t;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
254 次 |
最近记录: |