我有一个模板函数auto Run(Func f, Args&&... args)
,它适用于各种参数和一个要执行的函数。
如果我要执行的函数设置了默认参数,则在不单独指定每个参数的情况下,我不能将此函数用于Run
函数。参见以下示例:
#include <functional>
template<typename Func, typename ...Args>
auto Run(Func f, Args&&... args)
{
return f(std::forward<Args>(args)...);
}
int Int(int a, int b = 2){ return a + b; }
int main()
{
Run(Int, 3, 2); // does compile, because every parameter is set
Run(Int, 3); // does not compile
}
有没有一种方法可以在不改变函数调用方式的情况下实现这两种功能?我只想在可能的情况下更改模板化的函数
一个可能的解决方案(从C++14开始(是将Int()
函数封装在通用lambda 中
Run([](auto && ... as)
{ return Int(std::forward<decltype(as)>(as)...); }, 3, 2);
Run([](auto && ... as)
{ return Int(std::forward<decltype(as)>(as)...); }, 3);
通过这种方式,编译器直接管理Int()
函数的调用,维护第二个参数的默认值并使用它
问题是参数默认值不是函数签名的一部分,因此以下函数
int Int_0 (int a, int b){ return a + b; }
int Int_1 (int a, int b = 2){ return a + b; }
int Int_2 (int a = 1, int b = 2){ return a + b; }
是具有相同签名的函数,因此具有相同类型(int(int, int)
(。
如果将Int_2()
传递给接受int(int, int)
的函数,或者传递给推断为int(int, int)
的模板参数(在Run()
的情况下(,则默认值是宽松的。