2014-07-06 31 views
18

我正在使用Visual Studio 2012,而且我发现有些奇怪的东西。我不是在编写一些我需要在多个编译器中兼容的东西,但它可能会变得更晚(当代码放在Web上时,用户不想要编译器错误),但我不想写这是错误的,或者不是本地的。“自动”类型演绎编译虽然显式类型给出错误

因此,这是试验的代码:

class A{ 
    class B{ 
     public: 
     int i; 
    }; 
    B myB; 
public: 
    B& getB() { return myB; } 
}; 

int main() 
{ 
    A a; 
    A::B& b = a.getB(); 
    auto& b2 = a.getB(); 
} 

第一线的内侧主弹出error C2248: 'A::B' : cannot access private class declared in class 'A'而第二线通常编译。我想知道,汽车应该这样工作还是这是Visual Studio中的另一个错误?

我没有任何其他的编译器,我可以

测试它你甚至可以写的东西一样std::cout << b2.i << "\n";和它编译完美的罚款

按πάνταῥεῖ的评论,我想ideone用gcc 4.8 .1和它以相同的方式编译,第一行是错误,第二行是完全正确的。

+4

_'PS:我没有任何其他编译器可以用'__对其进行测试:http://isocpp.org/blog/2013/01/online-c-compilers特别是http://rise4fun.com/ vcpp –

+1

有趣。我从来没有考虑过这样的事情的合法性,但它似乎也用gcc和clang编译。 –

+0

用'main'中的代码初始化'b'和'b2',输出语句导致[*未定义的行为*](http://en.wikipedia.org/wiki/Undefined_behavior)为'b'和' b2'是对已经被破坏的对象 –

回答

10

我相信它应该像那样工作。访问适用于名称,而不是它们引用的实体。

即使没有auto它始终是合法的,例如,将getB的结果传递给期望B的函数。

+1

此外,如果您创建一个私有类的公共'typedef',使用'typedef''d名称在使用私有类名称时不会引发错误。 – Frxstrem

+3

或typedef:http://stackoverflow.com/questions/13532784/why-can-i-use-auto-on-a-private-type – kobigurk

+0

“访问适用于名称,而不是它们所指的实体”, *有点*。例如,C + 11§12.1/ 1“构造函数没有名称”。可以说,析构函数也没有名字,事实上在C++ 11中,至少有一个(非规范的)注释以这种方式论证。 –

3

auto应该这样工作,是的,是的,这意味着它可以暴露私人类型。