Использование enum в качестве аргумента типа шаблона в С++

Существуют ли какие-либо ограничения/проблемы с использованием перечисления в качестве шаблона (типа) в С++?

Пример:

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

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

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

// ....

MyTemplate<MyEnum> MyInstance;

Моя фактическая проблема с использованием MSVС++ через VS 2008 (SP1) на Win32/x86 - это несколько ошибок компиляции (= ошибки, сообщаемые компилятором) в связи с классами, использующими enums в качестве аргументов шаблона. Поскольку мой проект, к сожалению, стал немного сложным (вы можете считать это ошибкой проектирования: P), классы шаблонов, поднимающие эти ошибки, выводятся, вложены и даже специализируются на класс с параметром шаблона перечисления.

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

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

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


Edit

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

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

Ответы

Ответ 1

Ссылаясь на исходный вопрос:

Существуют ли какие-либо ограничения/проблемы с использованием перечисления в качестве шаблона (типа) в С++?

Я не нашел ни одного - и я не думаю, что он есть. Это может оказаться плохой идеей, потому что этот метод часто не используется, поэтому могут быть несколько (более) компиляторных ошибок, связанных с этим, так же, как сказал 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 специализация

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


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

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

Ответ 2

Да, есть ограничения. Например, вы не можете использовать анонимное перечисление в качестве аргумента шаблона в соответствии с С++ 03 14.3.1[temp.arg.type]/2

Локальный тип, тип без привязки, неназванный тип или тип, составленный из любого из этих типов, не должны использоваться как шаблон-аргумент для параметра типа шаблона.

Таким образом, следующий код недействителен в С++ 03:

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

enum {A};

int main() {
  f(A);
}

Это действительно в С++ 11.

Ответ 3

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

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

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