Есть ли какие-либо ограничения / проблемы с использованием перечисления в качестве аргумента шаблона (типа) в 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 строк кода), но эта мне кажется очень странной.
Любые предложения, как выяснить, является ли он компилятором?
Ссылаясь на исходный вопрос:
есть ли какие-либо ограничения / проблемы с использованием перечисления в качестве аргумента шаблона (типа) в 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
Для этих простых примеров все работает нормально и, как и ожидалось , а enum отлично работает как любой другой тип в качестве аргумента типа шаблона (= я не вижу причин для проблем).
Изначально я представил пример в вопросе, чтобы показать, что я имел в виду под этим вопросом (перечислить как аргумент типа шаблона, показать возможные варианты использования как тип аргумента члена или метода и так далее). Чтобы предоставить немного предыстории, то есть , почему я задал этот вопрос (представьте, что я спросил «есть ли проблемы с int»), я упомянул эти странные проблемы при компиляции моего настоящего проекта.
Мне очень жаль, что я не смог извлечь фрагмент, который сам по себе является полным и воспроизводит ошибки, меньше всего я смог получить, это 2k строк кода, разделенных на 4 файла, где «синтаксическая ошибка: 'public'» и некоторые другие синтаксические ошибки возникли, когда я компилировал проект, и они появлялись / исчезали при определенных обстоятельствах, при удалении комментария или повторном построении (= удалении промежуточных файлов).К сожалению, перестройка не помогает в исходном проекте, где мне пришлось заменить специализацию с типа перечисления на int.
Итак, спасибо всем за ваши подсказки и подсказки. Основная проблема кажется мне ошибкой компилятора, что делает вопрос немного бессмысленным, поскольку ответ кажется просто «нет - нет ограничений на использование перечисления в качестве аргумента типа шаблона» . Простите за неудобства.
MSVC странно обрабатывает параметры шаблона перечисления (значения). Иногда перечисления переводятся в int
некорректно, а операторы не определены должным образом. Похоже, что они не тестируют шаблонизатор с enum
типами.
Доказать, что это ошибка компилятора, очень просто: вставьте корректный код и посмотрите, успешно ли он компилируется. Ваш пример явно совместим, так что проблема (или ошибка, в любом случае) - в нем.
Edit: при ближайшем рассмотрении вы говорите, что пример не воспроизводит ошибку. Ни мы, ни кто-либо другой не сможет вам помочь, пока вы не приведете пример, который воспроизведет ошибку.