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