【发布时间】:2012-01-06 14:18:58
【问题描述】:
我一直在使用可变参数模板,它在 C 和 C++ 之间的接口中充当异常防火墙。模板只接受一个函数,后跟 N 个参数,然后在 try catch 块中调用该函数。这一直运行良好,不幸的是,我现在要调用的函数之一需要一个额外的默认参数。结果函数名没有解析,模板编译失败。
错误是:
perfect-forward.cpp: 在函数
‘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: 从这里实例化
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)...));
};
};
在使用 2 或 3 个参数调用 cfollowing 构造函数时有效...
MyClass1( const string& arg1, double d, const vector<int>&v = vector<int>{} )
【问题讨论】:
-
(顺便说一句,应该是
f(std::forward<Args>(params)...);。)
标签: c++ c++11 variadic-templates