Я использовал вариативный шаблон, который действует как межсетевой экран исключений в интерфейсе между C и C ++. Шаблон просто принимает функцию, за которой следуют N аргументов, и вызывает функцию внутри блока try catch. Это работает нормально, к сожалению, одна из функций, которые я хочу вызвать, теперь принимает дополнительный аргумент по умолчанию. В результате имя функции не разрешается, и шаблон не компилируется.
Ошибка:
perfect-forward.cpp: В функции
'void FuncCaller (Func, Args && ...) [with Func = void (*) (const std :: basic_string
:& , double, const std :: vector &), Args = {const char (&) [7], double}] '
perfect-forward.cpp: 69: 41: создан отсюда
perfect-forward.cpp: 46: 4: ошибка: слишком мало аргументов для функции
Упрощенная версия кода выглядит следующим образом:
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;
}
Если этот код работает или я слишком многого жду от компилятора?
Примечание: я тестировал использование идеальной пересылки с конструкторами, которые имеют аргументы по умолчанию, и код компилируется и работает, как ожидалось,
то есть:
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)...));
};
};
работает при вызове c следующий конструктор с 2 или 3 аргументами ...
MyClass1( const string& arg1, double d, const vector<int>&v = vector<int>{} )