2010-05-14 35 views
3

我有這樣C++使用的typedef非內聯函數

template< typename T > 
class vector { 
    public: 
    typedef T &  reference; 
    typedef T const & const_reference; 
    typedef size_t size_type; 

    const_reference at(size_t) const; 
    reference at(size_t); 
在同一個文件

template< typename T > 
typename vector<T>::const_reference // Line X 
vector<T>::at(size_type i) const 
{ 
    rangecheck(); 
    return elems_[ i ]; 
} 


template< typename T > 
reference        // Line Y 
vector<T>::at(size_type i) 
{ 
    rangecheck(); 
    return elems_[ i ]; 
} 

線X

,後來一類編譯罰款,但Y線上不能編譯。從G ++(4.4.1版本)的錯誤信息是:

foo.h:Y: error: expected initializer before 'vector' 

由此我推測,如果我想有非內聯函數,那我也完全限定的typedef名稱作爲線X(請注意,size_type沒有問題。)

但是,至少對我而言,Line X看起來笨拙。

有沒有其他方法?

+0

接受的答案是不正確的。 – 2010-05-16 01:07:10

回答

4

是的,在超類成員函數定義中,您必須爲嵌套返回類型使用完全限定名稱。這個BTW與模板無關。對於非模板類也是如此。

在你的情況下,它是一個模板類,因此,因爲你使用的是一個限定名稱來引用依賴模板類中的嵌套類型,所以你必須在關鍵字typename前加上它。

但是,你只需要限定返回類型。參數類型不需要資格

template< typename T > 
typename vector<T>::const_reference 
    vector<T>::some_method(const_reference r) const 
{ 
    // ... 
} 

您可以選擇使用一個合格的名稱爲參數類型爲好,但在這種情況下,你會做同樣的事情,與返回類型(同樣的原因):與typename關鍵字

template< typename T > 
typename vector<T>::const_reference 
    vector<T>::some_method(typename vector<T>::const_reference r) const 
{ 
    // ... 
} 
+0

@AndreyT:參數類型確實需要合格的,如果他們依賴於模板參數。 – 2010-05-14 02:05:00

+0

@Eddy Pronk:有趣。我無法在標準中找到明確的答案。然而,Comeau Onine成功地從模板類中的參數列表中找到*非限定類型的名字(暗示我是對的)。 G ++也是這樣做的。你能引用標準中會支持你的說法的地方嗎?我並不是說你錯了。而且,我會說,你所說的話很有道理,而且是一個合乎邏輯的事情。然而,編譯器不同意。 – AnT 2010-05-14 04:57:21

+0

@AndreyT:我沒有試圖在標準中找到它。我看了Effective C++ Item 42.看到我的答案。 – 2010-05-14 05:25:25

2

你是對的;該類型需要被限定,因爲您的typedef已經在類的範圍內給出,而不是在全局範圍內。我不知道如何在不污染全球範圍的情況下進行美化,這是一個壞主意。但是,它看起來像你的功能很短,所以你爲什麼不簡單地將它們定義爲內聯?這將爲您節省大量額外的打字費用,恕我直言,這更容易閱讀。

3

從有效的C++項目42加前綴:「任何時候你指的是嵌套依賴類型名在模板中,您必須立即由字類型名在它前面。」 size_t不嵌套在依賴於模板參數的任何內部。您確實鍵入了它,但它始終是size_t。

這就是它的樣子size_type DID取決於模板參數。

#include <cstddef> 

template< typename T > 
class vector { 
    public: 
    typedef T &  reference; 
    typedef T const & const_reference; 

    const_reference at(typename T::size_type) const; 
    reference at(typename T::size_type); 
}; 

template< typename T > 
typename vector<T>::const_reference 
vector<T>::at(typename T::size_type i) const 
{ 
    // ... 
} 

template< typename T > 
typename vector<T>::reference 
vector<T>::at(typename T::size_type i) 
{ 
    // ... 
} 

struct Foo 
{ 
    typedef size_t size_type; 
}; 

int main() 
{ 
    vector<Foo> f; 
    return 0; 
} 

size_type是Foo的嵌套類型。