Использование enum в качестве аргумента типа шаблона в C ++ - PullRequest
16 голосов
/ 15 августа 2010

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

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

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

Заранее благодарен за любой совет или подсказку!


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

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

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

Ответы [ 3 ]

7 голосов
/ 03 июля 2014

Да, есть ограничения.Например, вы не можете использовать анонимное перечисление в качестве аргумента шаблона в соответствии с 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, хотя.

4 голосов
/ 15 августа 2010

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

Есть ли какие-либо ограничения / проблемы с использованием аргумента enum в качестве шаблона (типа) в 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 specialization

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

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

0 голосов
/ 15 августа 2010

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

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

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

...