2010-08-14 642 views
15

在C++中是否存在使用枚舉作爲模板(類型)參數的限制/問題?在C++中使用枚舉作爲模板類型參數

實施例:

enum MyEnum 
{ 
    A, B, C, D, E 
}; 

template <typename _t> 
class MyTemplate 
{ 
public: 
    _t value; 

    void func(const _t& param) { /* .... */ } 
}; 

// .... 

MyTemplate<MyEnum> MyInstance; 

我使用MSVC++經由在Win32 VS 2008(SP1)/ x86的實際問題是(由編譯器報告=錯誤)幾個編譯錯誤相關聯地使用枚舉如類模板參數。由於我的項目不幸已變得有點複雜(你可以認爲這是一個設計錯誤:P),引發這些錯誤的模板類是派生的,嵌套的,甚至專用於帶有枚舉模板參數的類。

嘗試構建時,編譯器會在只有註釋的行中報告許多錯誤/無用的錯誤,例如「C2059:語法錯誤:'public'」。他們中的很多人可以通過替換類似於示例const _t & param by _t(即複製參數)的方法來解決這些問題,但我既不能解決所有這些錯誤,也不知道爲什麼「幫助」。 **我知道,上面這個簡單的例子編譯了W/O錯誤。

使用int而不是枚舉,我的項目編譯W/O錯誤。

在此先感謝您的任何提示或提示!


編輯

畢竟,我認真考慮這是一個編譯器錯誤。當我試圖用簡化的代碼重現錯誤時,我只在所有「構建」的50%中得到它們,不是非常確定的:
例如,試圖編譯,並報告了這些錯誤。重建 - 不變。刪除評論,建立 - 沒有改變。重建 - 然後:沒有錯誤,編譯好。

我已經遇到了一些編譯器錯誤(2或3我猜在20k代碼行內),但這個對我來說很奇怪。
任何建議如何找出它是否的編譯器?

+3

「試圖編譯時,編譯器會報告許多錯誤/無用的錯誤」這些「無用的」錯誤通常會對錯誤和錯誤進行非常詳細的描述。只要閱讀編譯器輸出,而不是「錯誤列表」。 – SigTerm 2010-08-14 23:08:04

+0

感謝提示,但我做到了。我總是這麼做^^ 但它沒有幫助我...錯誤:錯誤C2059:語法錯誤:'公共'錯誤C2143:語法錯誤:缺少'>'之前';'錯誤C2143:語法錯誤:缺少';'之前'}'致命錯誤C1004:發現意外的文件結束(然後一些其他錯誤,與此問題無關)所有這些僅在使用枚舉時出現並在使用int時出現消失 – dyp 2010-08-14 23:15:11

+0

這對我來說看起來很完美。這是一個編譯器錯誤或者你的錯誤,如果你猜測,99.9%的賭注就是你。但是,您發佈的代碼段沒有任何問題。請發佈一個完整的小樣本,以及它創建的確切編譯器錯誤。 – Omnifarious 2010-08-14 23:18:47

回答

4

參照原題:

are there any restrictions/problems using an enum as template (type) argument in C++?

我沒有發現任何 - 我不認爲有任何。這可能會變成一個糟糕的主意,因爲這種技術並不經常使用,所以可能會有一些(更多)與此相關的編譯器錯誤,就像Potatoswatter所說的那樣。
請看下面的例子:

enum MyEnum : int 
{ 
    A, B, C, D 
}; 

template <typename _t> class MyTemplate 
{ 
public: 
    void print() 
    { 
     cout << "not using any specialisation" << endl; 
    } 
}; 
    template <> class MyTemplate <MyEnum> 
    { 
    public: 
     void print() 
     { 
      cout << "MyEnum specialisation" << endl; 
     } 
    }; 
    template<> class MyTemplate <int> 
    { 
    public: 
     void print() 
     { 
      cout << "int specialisation" << endl; 
     } 
    }; 

template <typename _t> void print(_t param) 
{ 
    MyTemplate<_t> m; 
    m.print(); 
} 


int main() 
{ 
    print(A); 
    print(5); 

    return 0; 
} 

輸出是:

MyEnum specialisation
int specialisation

對於這些簡單的例子,一切工作正常,並預期和枚舉完美的作品爲任何其他類型的模板類型爭論(=我沒有看到任何問題的原因)。

最初,我在問題中引入了示例來說明我的問題(enum作爲模板類型參數,顯示可能的用法,成員或方法參數類型等)。爲了提供一些背景知識,例如爲什麼我問了這個問題(想象我問到「int有什麼問題」),我提到了編譯我的實際項目的這些奇怪的問題。
對不起,我無法提取它本身完成並重現錯誤的代碼片段,至少我可以得到的是將2k行代碼拆分爲4個文件,其中「語法錯誤:'public'」和編譯項目時出現了一些其他語法錯誤,並且在刪除註釋或重新構建(=刪除中間文件)時,在某些情況下它們出現/消失。不幸的是,重建對原始項目沒有幫助,我不得不將專業化從枚舉類型替換爲int。

所以,謝謝大家的提示和提示。根本問題在我看來是一個編譯器錯誤,是什麼使問題有點毫無意義,因爲答案似乎只是「不 - 沒有限制使用枚舉作爲模板類型參數」。抱歉給你帶來不便。

0

MSVC奇怪地處理枚舉(值)模板參數。枚舉有時被錯誤地提升爲int,並且操作符的定義不正確。看起來他們並不真正使用enum類型來測試模板引擎。

證明這是一個編譯器錯誤很簡單:將有效的代碼放入並觀察它是否成功編譯。 你的例子顯然是合規的,所以問題(或者錯誤,無論如何)都是他們的。

編輯:仔細觀察你說的那個例子確實重現bug。直到你製作一個例子,我們和其他任何人都不能幫助你。

+0

可以證明編譯器只有兩種方式存在缺陷: a)根據相關標準驗證 b)讀取文檔並檢查它是否是已知問題/缺陷 – Chubsdad 2010-08-15 03:07:03

+0

OP isn' t雖然提供了enum * value *作爲模板參數,但是enum * type *是參數。 – 2010-08-15 11:56:49

7

是的,有限制。例如,您可以根據C++ 03 14.3.1[temp.arg.type]/2

A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter.

不能使用匿名枚舉作爲模板參數,所以下面的代碼是無效的C++ 03:

template <typename T> 
void f(T) {} 

enum {A}; 

int main() { 
    f(A); 
} 

它是有效的在C++ 11中。