Getting around access specifiers with C++0x decltype
Consider the following code:
class A
{
private:
class B {};
public:
B f();
};
A a;
A::B g()
{
return a.f();
}
The compi开发者_JAVA百科ler rejects this - g cannot return A::B because A::B is private.
But suppose I now use decltype to specify the return value of g:
class A
{
private:
class B {};
public:
B f();
};
A a;
decltype(a.f()) g()
{
return a.f();
}
All of a sudden it compiles fine (with g++ >= 4.4).
So I've basically used decltype to get around an access specifier in a way I would not have been able to in C++98.
Is this intentional? Is this good practice?
Access only applies to names (and as a special case, to constructors/destructors). It doesn't apply to entities themselves. The spec further elaborates
[ Note: because access control applies to names, if access control is applied to a typedef name, only the accessibility of the typedef name itself is considered. The accessibility of the entity referred to by the typedef is not considered. For example,
class A { class B { }; public: typedef B BB; }; void f() { A::BB x; // OK, typedef name A::BB is public A::B y; // access error, A::B is private }
— end note ]
So what you have disovered here isn't surprising. You can get hold of the type A::B
even in C++03, when taking the address of f
by saying &A::f
and passing it to a function template deducing the return type.
精彩评论