Я попытался построить случай, который не требует имени или шаблона, но все же дает переменную или шаблон в зависимости от того, является ли данное имя t
пакетом параметров функции или нет
template<typename T> struct A { template<int> static void f(int) { } };
template<typename...T> struct A<void(T...,...)> { static const int f = 0; };
template<typename> using type = int;
template<typename T> void f(T t) { A<void(type<decltype(t)>...)>::f<0>(1); }
int main() {
f(1);
}
Вышеуказанное относится к static const int
и выполняет сравнение. Только что T t
был изменен как пакет и сделать f
ссылкой на шаблон, но GCC не нравится ни
template<typename ...T> void f(T ...t) { A<void(type<decltype(t)>...)>::f<0>(1); }
int main() {
f(1, 2, 3);
}
GCC жалуется на первый
main.cpp:5:68: error: incomplete type 'A<void(type<decltype (t)>, ...)>' used in nested name specifier
template<typename T> void f(T t) { A<void(type<decltype(t)>...)>::f<0>(1); }
И для второго
main.cpp:5:74: error: invalid operands of types '<unresolved overloaded function type>' and 'int' to binary 'operator<'
template<typename ...T> void f(T ...t) { A<void(type<decltype(t)>...)>::f<0>(1); }
У меня есть несколько вопросов
- Работает ли указанный выше код в соответствии с языком или есть ошибка?
- Поскольку Clang принимает оба варианта, но GCC отклоняет, я хотел спросить, какой компилятор прав?
-
Если я удалю тело первичного шаблона, то для случая
f(1, 2, 3)
Clang жалуетсяmain.cpp:5:42: error: implicit instantiation of undefined template 'A<void (int)>'
Обратите внимание, что он говорит
A<void (int) >
, в то время как я ожидалA<void (int, int, int)>
. Как это происходит? Является ли это ошибкой в моем коде - то есть она неформальная, или это ошибка в Clang? Кажется, я помню отчет о дефекте о порядке расширения и подстановке шаблона псевдонима, является ли это актуальным и делает ли мой код плохо сформированным?