以默认参数作为参数的函数

Hyp*_*ino 5 c++ function-pointers function default-arguments

所以,我知道你可以像这样传递一个函数作为参数:

int a(int x) {
    return x + 1;
}

int b(int (*f)(int), int x) {
    return f(x); // returns x + 1
}
Run Code Online (Sandbox Code Playgroud)

我还知道你可以有一个带有默认参数的函数,如下所示:

int a(int x = 1) {
    return x;
}

a(2); // 2
a();  // 1
Run Code Online (Sandbox Code Playgroud)

但是,如何将带有默认参数的函数传递给函数并保留此行为?

我尝试过以下方法:

int a(int x = 1) {
    return x;
}

a(2); // 2
a();  // 1
Run Code Online (Sandbox Code Playgroud)

int b(int (*f)(int), int x) {
    f(x); // works as expected
    f();  // doesn't work because there aren't enough arguments to f
}
Run Code Online (Sandbox Code Playgroud)

Tur*_*ght 3

无法使用函数指针转发默认参数值。

但如果你可以变成b一个模板函数,你就可以让它工作:

通过使用参数包operator()并显式调用,a我们使编译器有机会在需要时应用默认参数值:

int a(int x = 12) {
    return x + 1;
}

template<class T>
int b(T f, int x) {
    return f() + f(x);
}

struct AFnWrapper {
    template<class... Args>
    auto operator()(Args&&... args) {
        return a(std::forward<Args>(args)...);
    }
};

int main() {
   std::cout << b(AFnWrapper{}, 1) << std::endl; // 15
}
Run Code Online (Sandbox Code Playgroud)

一个较短的版本是只使用 lambda:

std::cout << b([](auto&&... args) { return a(std::forward<decltype(args)>(args)...); }, 1) << std::endl;
Run Code Online (Sandbox Code Playgroud)

如果你不需要完美的转发,你可以让它更短:

std::cout << b([](auto... args) { return a(args...); }, 1) << std::endl;
Run Code Online (Sandbox Code Playgroud)

神箭示例