Il codice di seguito lavora in gcc-4.8.2 Clang vs GCC - variadic parametro Template Pack seguito dal parametro con valore di default funziona in GCC 4.8, ma non clang 3,5
#include <iostream>
using namespace std;
template<typename... Args>
void func(Args... args, int optional = 0)
{
cout << optional << endl;
}
int main()
{
func(1);
func(2.1f); // converts 2.1 to int as 'optional' parameter
func<float>(3.3f); // Fine, prints '0'
func(); // gcc OK, fails to compile with clang-3.5
}
Ed Uscite:
$ ./a.out
1
2
0
0
Ma se non riesce a compilare con clang-3.5,
test_variadic.cpp:15:2: error: no matching function for call to 'func'
func();
^~~~
test_variadic.cpp:5:6: note: candidate function template not viable: requires at least argument 'args', but no arguments were provided
void func(Args... args, int optional = 0)
^
clang almeno avverte di la conversione implicita da un float a un int. Bene, possiamo correggerlo chiamando lo func<float>
che inserisce il parametro float nel template pack. Quindi, se commento fuori func()
, compila bene.
Non riesco a trovare nulla nel proverbio standard esplicitamente che il template pack variadic debba essere l'ultima cosa nella clausola-dichiarazione-parametro, solo che diventa un contesto non dedotto.
La mia confusione deriva dal motivo per cui clang non piace func()
quando func(1)
è perfettamente accettabile. Posso definire manualmente func(int optional = 4) { cout << optional << endl; }
e tutto va bene (ma anziché la funzione templated quando passa int
ho correttamente ottengo il specializzata func()
sia clang e gcc. Qual è enforcing clang che limita l'uso di func()
?
[lavora per clang 3.5] (http://coliru.stacked-crooked.com/a/6d2184a139335a5b) –
Ecco quale versione sto utilizzando, '$ clang --version Ubuntu versione clang 3.5-1ubuntu1 (tronco) (sulla base di LLVM 3.5) Obiettivo: x86_64-pc-linux-gnu ' e il comando 'clang ++ -std = c + +11 -O2 -Wall -pedantic test_variadic.cpp' – ilektron
Interessante. La stessa riga di comando ma con la versione "Ubuntu clang version 3.5.0-svn217640-1 ~ exp1 (branches/release_35) (basata su LLVM 3.5.0)" compila solo con l'avviso. –