2010-10-26 140 views
1

任何人都可以提出爲什麼這不會編譯?我想我在這裏錯過了一些重要的東西。編譯器是g ++ 4.2.1(在OS X上),錯誤是「預期的」;'在聲明迭代器的行上「之前」之前。奇怪的錯誤與C + +類模板

#include <vector> 

template <class T> 
class A { 
public: 
    struct SomeStruct { 
     T* ptr; 
     int i; 
    }; 

    typedef std::vector<SomeStruct> MyList; 

    void Func() 
    { 
     MyList::iterator it; 
    } 
}; 
+7

是的,你失去了一些東西重要:告訴我們的編譯器錯誤是什麼。 :) – 2010-10-26 14:35:38

+2

@Steve:不,編譯器無關緊要,只是g ++錯誤地接受了代碼。 – 2010-10-26 14:43:43

+0

是的,對不起'回合。編輯。 – 2010-10-26 14:49:11

回答

6

變化:

MyList::iterator it; 

到:

typename MyList::iterator it; 

我相信這有做不被肯定爲MyList::iterator是否應該是某種類型的值,編譯器(比如說iteratorMyList的靜態成員)或類型。 typename強制後者(正確)選項。

我相信從這裏開始相關標準的引用,第二個14.6:

在模板中使用的名字,假設除非適用的名稱查找發現一個類型名稱或名稱由合格未命名類型關鍵字typename

所以,你必須弄清楚什麼是「適用名稱查找」是的,但標準也與此示例跟進:

// no B declared here 

class X; 

template<class T> class Y { 
    class Z; // forward declaration of member class 

    void f() { 
     X* a1;  // declare pointer to X 
     T* a2;  // declare pointer to T 
     Y* a3;  // declare pointer to Y<T> 
     Z* a4;  // declare pointer to Z 
     typedef typename T::A TA; 
     TA* a5; // declare pointer to T’s A 
     typename T::A* a6; // declare pointer to T’s A 
     T::A* a7; // T::A is not a type name: 
        // multiply T::A by a7 
     B* a8;  // B is not a type name: 
        // multiply B by a8; ill-formed, 
        // no visible declaration of B 
     } 
}; 
+0

不,''typename'是**不**必須在這裏! – 2010-10-26 14:39:16

+1

@Armen Tsirunyan:我在發佈之前在本地編譯了他的代碼:添加'typename'修復了編譯器錯誤(「'it'之前的'expected';') – Thanatos 2010-10-26 14:40:57

+0

@Thanatos,@Alf:顯然我錯了,但我仍然不明白SomeStruct是一個獨立的名字... – 2010-10-26 14:48:13

4

你缺乏一個typename

#include <vector> 

template <class T> 
class A { 
public: 
    struct SomeStruct { 
     T* ptr; 
     int i; 
    }; 

    typedef std::vector<SomeStruct> MyList; 

    void Func() 
    { 
     typename MyList::iterator it; 
    } 
}; 

int main() {} 

此代碼使用g ++,msvc和Comeau Online進行編譯。

技術上SomeStruct是一個從屬名稱,這意味着什麼SomeStruct代表取決於模板參數。從編譯器的角度來看,std::vector可能專門用於某些A<T>::SomeStruct,其中該專業化沒有iterator typedef。所以你必須告訴可憐的編譯器。 ;-)

乾杯&心連心,

+0

唷,有道理。以前沒有得到過其中之一。謝謝Alf。 – 2010-10-26 14:52:45