C++ 访问私有嵌套类

C++ 访问私有嵌套类,c++,c++11,language-lawyer,C++,C++11,Language Lawyer,我做了一个简单的课程,它仍然在玩弄我的大脑: class A { private: class B {}; public: B getB() { return B(); }; }; 从C++03开始,这个类可以很好地编译,但是没有好看的方法将getB()的结果分配给左值,即: A::B b = A().getB(); 不编译 我通过使用中间模板获得了它,方式如下: template <typename T> struct HideType

我做了一个简单的课程,它仍然在玩弄我的大脑:

class A {
private:
    class B {};

public:
    B getB() {
        return B();
    };
};
从C++03开始,这个类可以很好地编译,但是没有好看的方法将
getB()
的结果分配给左值,即:

A::B b = A().getB();
不编译

我通过使用中间模板获得了它,方式如下:

template <typename T>
struct HideType {
    typedef T type;
};

HideType<A::B>::type b = A().getB();
但这是有效的:

auto b = A().getB();

这方面的标准有漏洞吗?

事实上
a::B B=a().getB()
不起作用是因为
B
a
的私有类成员。如果将其公开,则代码将编译。它与
auto
一起工作,因为
auto
只检查分配给它的对象的类型,而不需要调用对象的构造函数(就像
declval
)。因此,它将
A
类中存在的返回类型
getB
分配给
b
。您也可以通过以下方式更改代码:

decltype( declval<A>().getB() ) b = A().getB();
输出:-

true

由于
模板
可以识别
B
,因此
auto
也可以识别
B

A::B=A().getB()
不起作用的原因是
B
A
的私有类成员。如果将其公开,则代码将编译。它与
auto
一起工作,因为
auto
只检查分配给它的对象的类型,而不需要调用对象的构造函数(就像
declval
)。因此,它将
A
类中存在的返回类型
getB
分配给
b
。您也可以通过以下方式更改代码:

decltype( declval<A>().getB() ) b = A().getB();
输出:-

true
由于
模板可以识别
B
,因此
auto
也可以识别标准第11条(成员访问控制)中的
B

类的成员可以是
-私人的;也就是说,它的名称只能由声明它的类的成员和朋友使用。
-受保护;也就是说,它的名称只能由它所在的类的成员和朋友使用 由该类派生的类及其朋友声明(见11.4)。
-公众;也就是说,它的名称可以在任何地方使用,而不受访问限制

因此访问控制应用于名称

您不使用私人名称,因此根据标准第11条(成员访问控制)中的标准,这是合法的:

类的成员可以是
-私人的;也就是说,它的名称只能由声明它的类的成员和朋友使用。
-受保护;也就是说,它的名称只能由它所在的类的成员和朋友使用 由该类派生的类及其朋友声明(见11.4)。
-公众;也就是说,它的名称可以在任何地方使用,而不受访问限制

因此访问控制应用于名称


您不使用私人名称,因此它是合法的,根据标准

似乎,标准草案中存在这样的缺陷,但已被修改


可能是有编译器错误。声明
auto b=A().getB()
涉及到
自动
类型说明符的模板参数推导,因此根据C++11标准,它应该是格式错误的,因为该类型推导失败。

看起来,标准草案中存在这样的缺陷,但已由


可能是有编译器错误。声明
auto b=A().getB()涉及到
自动
类型说明符的模板参数推导,因此根据C++11标准,它应该是格式错误的,因为类型推导失败。

相关:我无法编译,您能在哪里显示MCVE吗?你可能会对litb的另一个选择感兴趣。相关:我无法编译,你能给我一个MCVE它发生在哪里吗?你可能会对litb的另一个选择感兴趣。“它与
auto
一起工作,因为
auto
就是这样!!!!它只会检查分配给它的类型是否有效”这完全是胡说八道。而
decltype
是C++11,就像
auto
,那么推荐它有什么意义呢?这只是一个额外的信息,告诉OP你可以访问
B
的对象,甚至不用
auto
“它与
auto
一起工作,因为
auto
就是这样的!!!!它只会检查分配给它的类型是否有效。”这完全是胡言乱语。
decltype
是C++11,就像
auto
,那么推荐它有什么意义呢?这只是一个额外的信息,告诉OP你可以访问
B
的对象,甚至不用
auto
auto b = A().getB();