错误:为参数1提供了默认参数

149

我在下面的代码中遇到了这个错误信息:

class Money {
public:
    Money(float amount, int moneyType);
    string asString(bool shortVersion=true);
private:
    float amount;
    int moneyType;
};

起初我以为在C++中不允许将默认参数作为第一个参数,但实际上是可以的。


你能提供更多细节吗? - Etienne de Martel
我在Windows上使用带有MinGW 5.1.6的Eclipse CDT。 - pocoa
2个回答

317
你可能正在函数实现中重新定义默认参数。它应该只在函数声明中定义。
//bad (this won't compile)
string Money::asString(bool shortVersion=true){
}

//good (The default parameter is commented out, but you can remove it totally)
string Money::asString(bool shortVersion /*=true*/){
}

//also fine, but maybe less clear as the commented out default parameter is removed
string Money::asString(bool shortVersion){
}

1
现在它说:“Money::asString()”与类“Money”中的任何一个不匹配。 - pocoa
1
@pocoa,你仍然需要保留bool shortVersion参数,只需删除或注释掉= true即可。 - Yacoby
@Yacoby:谢谢,你是对的。这毫无意义,非常混乱。 - pocoa
13
@pocoa:实际上,这是有道理的。如果你为参数提供默认值,这些值将在调用函数时被填充。因此,这些值必须在函数的声明中出现,因为调用方需要看到它们。如果你不得不在定义中重复它们,那就会变得多余且更难维护。(这也是我不同意 Yacoby 在实现中注释掉默认参数的原因。以我的经验,在真正的项目中,这样的注释迟早会与声明不一致。) - sbi
当接口和实现彼此不同时,记住实际定义变得更加困难。因此,您需要每次都检查标题文件。实际上,我喜欢第二种用法,它注释了默认参数。 - pocoa
2
实际定义是 std::string Money::asString(bool)。请注意,它甚至不包括参数的名称。事实上,在声明和定义中可以使用不同的名称。(在大型项目中,这很重要-出于任何原因-你想在定义中更改名称,但不希望重新编译依赖于声明的数百万行代码。) - sbi

15

我最近犯了一个类似的错误,这是我解决它的方法。

当有一个函数原型和定义时,在定义中未指定默认参数。

例如:

int addto(int x, int y = 4);

int main(int argc, char** argv) {
    int res = addto(5);
}

int addto(int x, int y) {
    return x + y;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接