2014-03-27 99 views
3

我发现自己具有嵌套类和具有相同名称的成员函数。该成员函数旨在返回嵌套类的一个实例:具有相同名称的嵌套类和成员函数

class Foo 
{ 
public: 
    class Lock 
    { 
     // Operations that require the lock... 
    }; 

    Lock Lock() noexcept {return Lock;} 
}; 

这种理解没有工作,所以我一直在寻找办法解决它,并试图:

return typename Foo::Lock(); 

这对于g工作得很好++ 4.7和4.8,但是当上铛++ 3.4运行我得到的错误:

没有C++ 11:error: typename specifier refers to non-type member 'Lock' in 'Foo' 用C++ 11:'error: typename specifier refers to non-type member 'Lock' in 'Foo'

这导致我的问题:

  • 其中哪些是正确的?
  • 有没有办法在成员函数中引用嵌套类,如示例中所示?

回答

1

我建议不要这样做,因为它会让代码真的难以阅读。但是如果你真的想继续前进,你必须保留嵌套类的前缀class关键字。当这句法无效,使用typedef:

class Foo 
{ 
public: 
    class Lock 
    { 
     // Operations that require the lock... 
    }; 

    class Lock Lock() noexcept { 
     typedef class Lock cLock; 
     return cLock(); 
    } 
}; 

Live example

至于错误,铛是在这一个正确的。你不能像这样使用typename来消除歧义,我不认为它应该可以在模板之外使用。

标准的引用:

  • C++11[class.name]§4指定如何Lock隐藏class Lock以及如何为class Lock进行访问。

  • C++11[class.name]§2指出:

    如果一个类名称被在一个范围内声明,其中的变量,函数,或具有相同名称的枚举还声明,那么当两个声明是在范围中,类可被称为仅使用阐述型说明符

    一种阐述型说明符class X形式。请注意,这意味着typename Foo::Lock不是引用它的有效方式。

+1

感谢您的解决方法。至于正确性,如果你可以指向标准的相关部分,那将是非常好的:) – DrYap

+0

我正要回答C++ 11草案标准草案中实际上正确的部分是'9.1'。 –

+0

您可以使用'::'aswell访问类名称,而不仅仅是使用详细的类型说明符(标准说“当两个声明都在范围内”,这似乎是指“当名称可以使用不合格抬头”)。这是有效的:'Foo :: Lock :: bar();',如果'bar'是Lock嵌套类的成员函数。 –

相关问题