Natknąłem się na pewne interesujące zachowanie funkcji szablonów wariatów. Czy każdy może wskazać odpowiednie zasady w standardzie, które to definiują?Zaskakujące niezerowe zachowanie pakietów parametrów
GCC, ICC i MSVC skompiluj następujący kod pomyślnie (Clang nie, ale rozumiem, że jest to spowodowane błędami kompilatora).
template<class A, class... Bs, class C>
void foo(A, Bs..., C) { }
int main()
{
foo<int, int, int, int>(1, 2, 3, 4, 5);
}
W tym wywołaniu foo
argumenty szablonu są przewidziane A
i Bs
, następnie C
wyprowadza się int
.
Jednakże, jeśli po prostu odwrócić dwa ostatnie parametry szablonu:
template<class A, class C, class... Bs>
void foo(A, Bs..., C) { }
następnie allthreecompilers błędy rzut. Oto jeden z GCC:
main.cpp: In function 'int main()':
main.cpp:8:42: error: no matching function for call to 'foo(int, int, int, int, int)'
foo<int, int, int, int>(1, 2, 3, 4, 5);
^
main.cpp:4:6: note: candidate: template<class A, class C, class ... Bs> void foo(A, Bs ..., C)
void foo(A, Bs..., C) { }
^~~
main.cpp:4:6: note: template argument deduction/substitution failed:
main.cpp:8:42: note: candidate expects 4 arguments, 5 provided
foo<int, int, int, int>(1, 2, 3, 4, 5);
^
Żeby było ciekawiej, nazywając tylko czterech argumentów invalid dla pierwszego foo
i valid na sekundę.
Wydaje się, że w pierwszej wersji foo
, C
musi wywnioskować, natomiast w drugim, C
musi być jawnie dostarczone.
Jakie zasady w standardzie definiują to zachowanie?
Powiedziałbym, że pierwszy przykład, ten, który kompiluje, nie powinien. Jest źle sformułowany. –
@SamVarshavchik Czy możesz wyjaśnić, dlaczego? – TartanLlama
Szablon jest jawnie tworzony z czterema parametrami. Szablon rozszerza te same parametry, co parametry do wywołania funkcji. Oczekuje się, że wywołanie funkcji zajmie cztery parametry. Przekazywanie pięciu rzeczywistych parametrów do wywołania funkcji, która oczekuje czterech parametrów, jest źle sformułowane. –