Ho utilizzato un modello variadic che funge da firewall di eccezione in un'interfaccia tra C e C++. Il modello prende semplicemente una funzione, seguita da argomenti N e chiama la funzione all'interno di un blocco catch try. Questo ha funzionato bene, purtroppo una delle funzioni che desidero chiamare ora richiede un argomento di default aggiuntivo. Di conseguenza, il nome della funzione non viene risolto e il modello non riesce a compilare.Modelli Variadic, Inoltro perfetto alle funzioni con argomenti predefiniti
L'errore è:
perfect-forward.cpp: In function
‘void FuncCaller(Func, Args&& ...) [with Func = void (*)(const std::basic_string<char>&, double, const std::vector<int>&), Args = {const char (&)[7], double}]’
:
perfect-forward.cpp:69:41: instantiated from here
perfect-forward.cpp:46:4: error: too few arguments to function
Una versione semplificata del codice è il seguente:
template< class Func, typename ...Args >
void FuncCaller(Func f, Args&&... params)
{
try
{
cout << __func__ << " called\n";
f(params...);
}
catch(std::exception& ex)
{
cout << "Caught exception: " << ex.what() << "\n";
}
}
void Callee(const string& arg1, double d, const vector<int>&v = vector<int>{})
{
cout << __func__ << " called\n";
cout << "\targ1: " << arg1 << "\n";
cout << "\td: " << d << "\n";
cout << "\tv: ";
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " " ));
cout << "\n";
}
int main()
{
vector<int> v { 1, 2, 3, 4, 5 };
FuncCaller(Callee, "string", 3.1415, v);
FuncCaller(Callee, "string", 3.1415); **// Fails to compile**
return 0;
}
Qualora questo codice di lavoro o sono in attesa di troppo dal compilatore?
Nota: Ho testato l'uso di inoltro perfetto con i costruttori che hanno argomenti di default e il codice compila e funziona come previsto,
cioè:
template<typename TypeToConstruct> struct SharedPtrAllocator
{
template<typename ...Args> shared_ptr<TypeToConstruct>
construct_with_shared_ptr(Args&&... params) {
return std::shared_ptr<TypeToConstruct>(new TypeToConstruct(std::forward<Args>(params)...));
};
};
opere quando si chiama il costruttore di cfollowing con 2 o 3 argomenti ...
MyClass1(const string& arg1, double d, const vector<int>&v = vector<int>{})
(Dovrebbe essere 'f (std :: inoltro (params) ...);', a proposito.) –