模板化参数中仿函数的默认参数

Default argument for a functor in a templated parameter

我想在我的函数中为仿函数参数设置一个默认的 lambda。

我知道可以像这样使用 structoperator():

struct AddOne {
    int operator()(int a) {
        return a+1;
    }
};

template <typename Functor = AddOne>
int run_old(int x, Functor func = AddOne()) 
{
    return func(x);
}

但我想知道是否有一种现代方法,考虑到 c++14/17/20 中标准的变化,使这项工作有效?

template <typename Functor>
int run_new(int x, Functor func = [](int a){ return a+1; }) 
{
    return func(x);
}

我不确定 Functor 的默认类型是什么,或者是否有我不知道的语法。

https://godbolt.org/z/Hs6vQs

C++11 你已经可以做到了:

template <typename Functor = int(int)>
int run_new(int x, Functor func = [](int a){ return a+1; }) 
{
    return func(x);
}

只需为此添加一个重载。

template <typename Functor>
int run_new(int x, Functor func) 
{
    return func(x);
}

int run_new(int x) 
{
    return run_new(x, [](int a){ return a+1; });
}

允许您解决无法将 lambda 表达式作为默认函数参数的问题。

不完全是 "modern",但您可以使用仅采用单个参数的非模板方法的普通旧重载:

int run_new(int x) 
{
    return func(x,[](int a){ return a+1;});  // calls the template overload
}

除了其他问题,您甚至可以避免使用模板:

int run_new(int x, std::function<int(int)> func = [](int a){ return a + 1; })
{
   return func(x);
}

我能想象的最好的传递一个变量

static constexpr auto defFunc = [](int a){ return a+1; };

template <typename Functor = decltype(defFunc)>
int run_new(int x, Functor func = defFunc) 
{
    return func(x);
}

只是为了好玩,在 C++20 中,我们有 (1) 未计算上下文中的 lambda 和 (2) 没有捕获的 lambda 是默认可构造的。结合这两个,你会得到:

template <typename Functor = decltype([](int a){ return a+1; })>
int run_new(int x, Functor func = {})
{
    return func(x);
}

Obligatory godbolt.