C ++:奇怪的是“私人”的错误
我从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 ++的bug?
执行以下任何操作会阻止发生的错误:
Test
转换为类,而不是模板类。 TheCatDog::Dog::bark();
CatDog::Dog::bark();
。 CrazyHouse
类并在Test
合并其内容。 CatDog
类,将其内容合并到Test
并将TheCatDog
别名更改为指向Test
。 标识符CatDog
上的名称查找会查找被声明为private
Test::CatDog
。 访问由CrazyHouse
执行,它不是Test
的friend
。 因此,这是对受保护成员的非法访问。
正如@sj0h所指出的那样,在C ++ 11中,您的示例变得有效,因为他们决定以与成员函数相同的方式扩展对嵌套类主体的访问。
C ++ 98:
嵌套类的成员对封闭类的成员没有特殊的访问权限,也没有对授予封闭类的友谊的类或函数的特殊访问权限; 应遵守通常的访问规则(第11条)。
C ++ 11:
嵌套类是成员,因此具有与其他成员相同的访问权限。
(会员有权访问封闭班的private
会员。)
但是,即使在4.9版本的最新版本中,这一变化似乎也未在GCC中实施。 所以,为了安全起见,添加friend
声明无妨。 这必须遵循成员的定义:
friend struct CrazyHouse;
请注意,这不会完成与C ++ 11更改完全相同的事情,因为friend
出货不是传递式的,而嵌套成员资格授予的访问权限是。
取决于我们正在讨论的C ++版本,编译器的行为可能被认为是错误或正确的。 看起来,如果我们在谈论C ++ 11时,clang的行为是正确的,如果我们正在谈论C ++ 98,那么它是不正确的。
stackoverflow项目C ++嵌套类访问应澄清。
链接地址: http://www.djcxy.com/p/77717.html上一篇: C++: Strange "is private" error
下一篇: Best Practice for Using a Dependency Injection / Service Locator Container?