Ответ 1
После запуска нескольких тестов, это, похоже, ошибка компилятора в MSVC. Несмотря на то, что он отлично работает с GCC, MSVC дает загадочную и бесполезную ошибку компилятора (идентичную тем, которые заданы в вашем вопросе), когда вы пытаетесь использовать traits<T>::val
внутри параметров шаблона для возврата S< E e >
.
Самое смешное, когда вы меняете S< E e >
, чтобы вместо этого взять целое число, оно работает. Рассмотрим этот пример, идентичный вашему, с различными именами:
enum E {
x
};
template <typename T>
struct traits {
static const E val = x;
};
template <E e>
struct S {
S(){};
};
template <typename T>
S< traits<T>::val > tricky(T t) {
return S< traits<T>::val > ();
};
int main() {
char thiskidwhowalksaround = 0;
S<x> s = tricky( thiskidwhowalksaround );
}
Теперь просто изменим одну вещь:
template <int e> // int instead of E
struct S {
S(){};
};
Программа затем компилирует (ссылки и работает) безупречно для меня. Если вы также вернетесь к оригиналу, а затем передайте значение E
напрямую, например:
template <typename T>
S< x > tricky(T t) {
// ^ here
return S< x > (); // <-- here
};
Затем программа компилирует файл. MSVC имеет проблему, когда он кусает пыль при попытке сделать следующее:
traits<T>::val
где val
- любой вид перечисления. Я на 99% уверен, что это недостаток в компиляторе. Это, по-видимому, отлично сформированный С++, поэтому я не могу сказать, что GCC делает что-то неправильно или расширяет-y, имея исходный фрагмент кода. Таким образом, лучшее, что я могу почерпнуть, заключается в том, что MSVC не хватает в надежности компилятора по сравнению с его сверстниками, но опять же.
Вы можете перестать читать здесь, потому что теперь я собираюсь немного рассказать о компиляторе MSVC.
begin<rant>
Это не то, что команда VС++ плоха или что С++ плохой, но из того, что я собираю команда компилятора и стандартные библиотеки в Microsoft - на момент написания - крошечный по сравнению с другими ведомства. Меня раздражает, что такой фундаментальный и важный язык и часть ядра MS-индустрии обладают такой сравнительно небольшой рабочей силой, что он не может идти в ногу с тем, что - за короткое время жизни - я считаю одним из самых медленных движущихся стандартов в мире. Я, конечно, не сбиваю людей, которые работают в команде VС++, но я глубоко озадачен тем, почему их больше не работает над тем, чтобы С++ не только ускорялся, но и улучшал работу компилятора и так же хорошо, как и другие продуктов.
end<rant>