C++:奇怪的";是私人的";错误
C++: Strange "is private" error
我从g++那里得到了一个非常不寻常的错误,声称类型别名是私有的。经过几个小时的代码缩减,我得到了以下最小的测试用例:
template <typename Dummy>
class Test {
struct CatDog {
static void meow ()
{
CrazyHouse::TheCatDog::meow();
}
struct Dog {
static void bark ();
};
};
struct CrazyHouse {
using TheCatDog = CatDog;
static void startMadness ()
{
TheCatDog::meow();
TheCatDog::Dog::bark();
}
};
public:
static void init ()
{
CrazyHouse::startMadness();
}
};
int main ()
{
Test<void> t;
t.init();
}
g++4.8.2的错误为:
test.cpp: In instantiation of 'static void Test<Dummy>::CatDog::meow() [with Dummy = void]':
test.cpp:19:29: required from 'static void Test<Dummy>::CrazyHouse::startMadness() [with Dummy = void]'
test.cpp:27:34: required from 'static void Test<Dummy>::init() [with Dummy = void]'
test.cpp:34:12: required from here
test.cpp:15:33: error: 'using TheCatDog = struct Test<void>::CatDog' is private
using TheCatDog = CatDog;
^
test.cpp:6:41: error: within this context
CrazyHouse::TheCatDog::meow();
^
Clang 3.4接受相同的代码。这里发生了什么,这是一个g++错误吗?
执行以下任何操作都可以阻止错误的发生:
- 将
Test
转换为一个类,而不是一个模板类 - 删除任何函数中的任何语句
- 将
TheCatDog::Dog::bark();
更改为CatDog::Dog::bark();
- 删除
CrazyHouse
类并在Test
中合并其内容 - 删除
CatDog
类,将其内容合并到Test
中,并将TheCatDog
别名更改为指向Test
对标识符CatDog
的名称查找会找到声明为private
的Test::CatDog
。从不是Test
的friend
的CrazyHouse
执行访问。因此,这是对受保护成员的非法访问。
正如@sj0h所指出的,在C++11中,您的示例变得有效,因为他们决定以与成员函数相同的方式扩展对嵌套类主体的访问。
C++98:
嵌套类的成员对封闭类的成员没有特殊访问权限,也没有对授予封闭类友谊的类或函数的特殊访问权限;应遵守通常的访问规则(第11条)。
C++11:
嵌套类是一个成员,因此具有与任何其他成员相同的访问权限。
(成员有权访问封闭类的private
成员。)
然而,即使在最近的4.9版本中,GCC中似乎也没有实现此更改。因此,为了安全起见,添加friend
声明不会有什么坏处。这必须在成员定义之后:
friend struct CrazyHouse;
请注意,这并不能完成与C++11更改完全相同的事情,因为friend
ship是不可传递的,而嵌套成员身份授予的访问权限是。
编译器的行为可以被认为是错误的或正确的,这取决于我们谈论的C++版本。如果我们谈论C++11,clang的行为似乎是正确的,如果我们谈论C++98,clang的行为则是不正确的。
stackoverflow项C++嵌套类访问应该澄清这一点。
相关文章:
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- 代码在main()中运行,但在函数中出现错误
- 释放错误后堆使用
- (C++)分析树以计算返回错误值的简单算术表达式
- Project Euler问题4的错误解决方案
- 我的字符计数代码计算错误.为什么
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 尝试导入pybind-opencv模块时出现libgtk错误
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 在某些循环内使用vector.push_back时出现分段错误
- MSVC多行宏编译器错误
- Arduino IDE 错误 - 无法找到数字文字运算符"运算符""f900ff"
- '&lt;'''&lt;'''&quot的模板类错误''令牌”
- 错误消息:"jj"的名称查找已更改为ISO"for"范围,(如果您使用"