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