簡體   English   中英

在C ++中使用enum作為模板類型參數

[英]Using enum as template type argument in 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;

我在Win32 / x86上通過VS 2008(SP1)使用MSVC ++的實際問題是與使用枚舉作為模板參數的類相關聯的幾個編譯錯誤(=編譯器報告的錯誤)。 遺憾的是,我的項目變得有點復雜(您可以將其視為設計錯誤:P),引發,嵌套甚至專門針對具有枚舉模板參數的類的模板類會引發這些錯誤。

嘗試構建時,編譯器會在只有注釋的行中報告許多錯誤/無用的錯誤,例如“C2059:語法錯誤:'public'”。 其中許多我可以通過替換類似於示例中的方法來修復const _t&param by _t(即復制參數),但我也無法解決所有這些錯誤,也不知道為什么這個“幫助” 。 **我知道,上面的簡單例子編譯沒有錯誤。

使用int而不是enum,我的項目編譯沒有錯誤。

提前感謝任何提示或提示!


編輯

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

我已經遇到了一些編譯器錯誤(我估計在20k行代碼中有2或3個),但這個在我看來非常奇怪。
任何建議如何弄清楚它是否是編譯器?

是的,有限制。 例如,根據C ++ 03 14.3.1[temp.arg.type]/2 ,您不能使用匿名枚舉作為模板參數

本地類型,沒有鏈接的類型,未命名的類型或從這些類型中的任何類型復合的類型不應該用作模板類型參數的模板參數。

所以下面的代碼在C ++ 03中無效:

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

enum {A};

int main() {
  f(A);
}

它在C ++ 11中有效。

參考原始問題:

在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專業化
int專業化

對於這些簡單的例子, 一切正常並且符合預期 ,並且枚舉與任何其他類型作為模板類型參數完美地工作(=我沒有看到任何問題的原因)。

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

所以,感謝大家的提示和技巧。 在我看來,潛在的問題是編譯器錯誤,是什么讓這個問題毫無意義,因為答案似乎只是“沒有 - 使用枚舉作為模板類型參數沒有限制” 抱歉給你帶來不便。

MSVC奇怪地處理枚舉(值)模板參數。 枚舉有時會被不正確地提升為int ,並且運算符定義不正確。 看起來他們並沒有真正用enum類型測試模板引擎。

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

編輯 :仔細觀察你說的那個例子重現bug。 在你做出一個例子之前,我們或其他任何人都無法幫助你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM