c++ 可变参数模板,完美转发到具有默认参数的函数

t3psigkw  于 2023-03-14  发布在  其他
关注(0)|答案(1)|浏览(140)

我一直在使用一个可变参数模板,它在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}]’中:
完全转发。cpp:69:41:从此处示例化
完全转发。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>{} )
u1ehiz5o

u1ehiz5o1#

我不认为有任何方法可以做到这一点。默认参数值不是函数签名的一部分。它们只是代码生成的简写,当你逐字地调用函数时,编译器会扩展它们。类似地,std::bind也不会选择默认参数。

相关问题