Использование enum в качестве аргумента типа шаблона в 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++ через VS 2008 (SP1) на Win32/x86-это несколько ошибок компиляции (=ошибки, сообщенные компилятором) в связи с классами, использующими перечисления в качестве аргументов шаблона. Поскольку мой проект, к сожалению, стал немного сложным (вы можете рассматривать это как ошибку дизайна: P), классы шаблонов, вызывающие эти ошибки производный, вложенный и даже специализированный на классе с параметром шаблона перечисления.

пытаясь построить, компилятор сообщает о многих неправильных / бесполезных ошибках, таких как" c2059: синтаксическая ошибка: "public "" в строках, где есть только комментарий. Многие из них я мог бы исправить, заменив в методах, подобных приведенному в Примере const _t& param на _t (т. е. копирование параметра), но ни я не мог исправить все эти ошибки, ни я понятия не имею, почему это "помогает". **Я знаю, простой пример выше компилирует без ошибок.

используя int вместо перечисления, мой проект компилирует без ошибок.

заранее спасибо за любой намек или подсказку!


редактировать:

В конце концов, я серьезно рассматриваю это как ошибку компилятора. Когда я попытался воспроизвести ошибки с упрощенным кодом, я получил их только в 50 % всех "сборок", не очень детерминированных:
Е. Г. попытался скомпилировать, и он сообщил эти ошибки. Перестроить-без изменений. Удалил комментарий, сборка - без изменений. Rebuild - и затем: нет ошибок, компилируется нормально.

Я уже встречал несколько ошибок компилятора (2 или 3, я думаю, в пределах 20k строк кода), но это кажется мне очень странным.
Любые предложения, как выяснить, если это is компилятор?

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 specialisation

для этих простых примерах все работает нормально и как положено и перечисление отлично работает как любой другой тип в качестве аргумента типа шаблона (=я не вижу причин для проблем).

Первоначально я представил пример в вопросе, чтобы показать, что я имел в виду с этим вопросом (перечисление как аргумент типа шаблона, показать возможные использования в качестве аргумента члена или метода типа и так далее). Чтобы обеспечить немного фона, т. е. почему Я задал этот вопрос (Представьте, что я спросил: "есть ли проблемы с int"), я упомянул эти странные проблемы при компиляции моего фактического проекта.
Мне жаль, что я не смог извлечь фрагмент, который сам по себе является полным и воспроизводит ошибки, по крайней мере, я мог бы получить 2K строк кода, разбитых на 4 файла, где "синтаксическая ошибка:" public "" и некоторые другие синтаксические ошибки были подняты при компиляции проекта, и они появлялись / исчезали при определенных обстоятельствах, при удалении комментария или восстановлении (= удаление промежуточных файлов). К сожалению, перестройка не помогает в первоначальном проекте, где мне пришлось заменить специализацию от типа перечисления до int.

Итак, спасибо всем за Ваши советы и подсказки. Основная проблема кажется мне ошибкой компилятора, что делает вопрос немного бессмысленным, так как ответ кажется просто "нет - есть нет ограничений при использовании перечисления в качестве аргумента типа шаблона". Извините за неудобства.


MSVC обрабатывает параметры шаблона перечисления (значения) странно. Перечисления повышаются до int иногда неправильно, и операторы не определены должным образом. Похоже, что они действительно не тестируют движок шаблонов с помощью enum типы.

доказать, что это ошибка компилятора, просто: поместите действительный код и посмотрите, успешно ли он компилируется. ваш пример, очевидно, совместим, поэтому проблема (или ошибка, в любом случае) у них.

редактировать: при ближайшем рассмотрении вы говорите, что пример делает не воспроизвести ошибку. Ни мы, ни кто-либо другой не сможем помочь вам, пока вы не приведете пример, который поможет.