功能默认参数将被忽略

amp*_*awd 18 c++ templates g++ c++11

对于这段简化的代码,我遇到了以下错误:

错误:函数std :: cout << f();的参数太少;

int g(int a = 2, int b = 1)
{
    return a + b;
}

template<class Func>
void generic(Func f)
{
    std::cout << f();
}

int main()
{
    generic(g);
}
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚为什么函数的默认参数f没有传递给函数的原因generic.它的行为就像f没有任何默认参数......

那有什么不对?

如何正确转发默认参数?

Bar*_*rry 22

g可能有默认参数,但类型&g仍然是int(*)(int, int),这不是可以不带参数调用的类型.在内部generic,我们无法区分 - 我们已经失去了关于默认参数的上下文.

您可以将glambda 包装起来以保留上下文:

generic([]{ return g(); });
Run Code Online (Sandbox Code Playgroud)

  • @ tobi303你不能用`bind`来完成 - 和这里一样的问题.必须是一个lambda. (4认同)

for*_*818 7

我认为这段代码的错误信息很好地证明了为什么这是不可能的:

int g(int a=0,int b=0){return 0;}

typedef int (*F1)(int);

int main() {
    F1 x = g;
}

error: cannot initialize a variable of type 'F1' (aka 'int (*)(int)') with
an lvalue of type 'int (int, int)': different number of parameters (1 vs 2)
    F1 x = g;
       ^   ~
Run Code Online (Sandbox Code Playgroud)

即使使用默认参数,类型g仍然是

int (*) (int,int)
Run Code Online (Sandbox Code Playgroud)

这就是实例化模板时推断出来的内容.

如果由于某种原因你不能使用C++ 11或更高版本(即没有lambdas,请参阅Barry的回答)并且你不介意一点样板,那么你可以使用一个函数对象:

#include <iostream>

struct g_functor {
    int operator()(int a=0,int b=0){ return a;}
};

template <typename T> void foo(T t) { t(); }

int main() { foo(g_functor()); }
Run Code Online (Sandbox Code Playgroud)

请注意,您必须创建一个g_functor将其作为参数传递的实例.