2013-05-11 61 views
2

例如,請考慮以下那裏是名nest1的衝突:我們是否需要將嵌套類型的成員參數加上「::」?

template <typename U> class nest1 {}; 

class cls { 
public: 
    template <typename V> class nest1 {}; 

    template <typename W> class nest2 { 
    public: 
     void bar(nest1<W> x); 
    }; 
}; 

template <typename W> 
void cls::nest2<W>::bar(nest1<W> x) {} // how does compiler know which nest<1>? 
  • 編譯器如何知道是否bar需要nest1<W>cls::nest1<W>如果我們不使用前綴cls::(如bar(cls::nest1<W> x)) ?
  • 無論如何明確加前綴cls::是否是一種好的做法?

注:編譯器實際選擇隱含聲明bar(cls::nest1<W> x)

+0

同樣,當你有一個全局變量,並與同名的靜態數據成員的。 – chris 2013-05-11 01:59:20

+0

因此,它只是剝離圖層並在最接近的父/祖類中找到所需的聲明? – mchen 2013-05-11 02:13:06

+0

哦,我認爲它會選擇全球性的。你應該在你的問題中指定。 – chris 2013-05-11 02:17:21

回答

0

每名成員後使用函數名也在詞法範圍內查找它的類。這導致以下(貌似)不一致的行爲,因爲正常的返回類型爲類的詞彙範圍內不

struct X{ 
    struct Y{}; 

    Y foo(Y); 
    Y bar(Y); 
}; 

// normal return type is before 'foo', needs explicit scope qualification 
// parameter doesn't (after 'foo') 
X::Y X::foo(Y y){ return y; } 

// trailing-return-type also doesn't (after 'bar') 
auto X::bar(Y y) -> Y{ return y; } 

對於standardese對於這一點,我們來看看§9.3 [class.mfct] p5

如果成員函數的定義在其詞類定義的詞彙之外,則應使用::運算符通過其類名稱限定成員函數名稱。 [注:在一個成員函數定義中使用的名稱(即,在包括默認參數(8.3.6參數聲明子句)或成員函數體)被查找所描述在3.4。末端音符] [...]

然後在§3.4.1 [basic.lookup.unqual] p8(不合格的名稱查找,例如,沒有::):

在一個成員函數的定義中使用的名稱(9.3 )的類X以下功能的聲明符-ID [...]應以下列方式之一進行申報:

  • [...]
  • X類的成員或者是基類的X(10.2)中的一員,或
  • [...]

(該說明符的IDS在我的例子是foobar

相關問題