2014-03-27 140 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嵌套類的成員函數。 –

相關問題