【问题标题】:C++ messed up: optional argument forced to be mandatoryC++ 搞砸了:可选参数强制是强制性的
【发布时间】:2018-08-18 16:29:20
【问题描述】:

我想要一个带有可选参数的函数。但是,VC++ 抛出了一个我无法理解的错误。代码很简单如下:

#include <iostream>
#include <iomanip>
#include <string>
using namespace std;

void myFunction(string something, int w);

int main()
{
    myFunction("a string");

    int a = 1;
}

void myFunction(string something, int w = 5)
{
    cout << something << " - " << w << endl;
}

它抱怨:

'myFunction': function does not take 1 arguments

但是,如果我将 myFunction() 移到 main() 之前,它不会出错。到底是怎么回事?请帮忙。谢谢。

【问题讨论】:

  • 把默认参数int w=5放在声明而不是定义中。
  • 如果我解决了您的问题,请不要忘记将我的答案标记为已接受。 :)

标签: c++ optional-arguments


【解决方案1】:

此错误是因为您在调用函数时有可选变量,但在声明中没有。

这将创建一个包含两个变量的函数:

void myFunction(string something, int w);

但是,这会使第二个变量成为可选的:

void myFunction(string something, int w=5);

你需要让声明有一个可选变量。

另外,我很惊讶您的编译器没有尝试吐出与重新定义相关的某种错误。 (这甚至可能是一个编译器错误!我将更新对此的研究。 更新: 看起来不像是编译器错误,但绝对是我希望拥有的功能. 即使它是一个错误,它也会与 linker 相关。)

【讨论】:

  • 天哪。我刚刚意识到我可能在一些旧代码中遇到了这个问题。我回答了一个我应该在几个月前问的问题。 编辑: 不。我不会聪明到使用声明。
  • 在定义中添加默认参数本身并没有错。这里的问题是默认参数在调用函数时不可见,因此调用必须有两个参数。在函数定义之后发生的调用可以用一个参数调用它。
  • @PeteBecker 好的。给我一点时间来更新我的答案。对吗?
【解决方案2】:

一些术语:这个

void myFunction(string something, int w);

是一个声明。这个

void myFunction(string something, int w) {
    // note the function body
}

通常称为定义。但它实际上既是定义,也是声明。为简单起见,我将继续称其为定义。

您的问题是 顺序很重要,特别是您声明、定义和调用函数的顺序。main() 的调用站点上,myFunction 的唯一可见声明采用字符串和一个整数并且没有默认参数。那个时候定义是不可见的,所以它根本不起作用。对于编译器,您似乎试图调用一个不存在的函数。

有两种解决方案:

  1. 将默认参数从定义移至声明。这是常见的做法。在大多数情况下,您在头文件中有声明(包括任何默认参数),而在 #include 头文件的 cpp 文件中有匹配的定义(没有默认参数)。
  2. 去掉声明,把定义移到main()上面。这是有效的,因为定义也是一个声明。

在这个简单的例子中,两者同样有效。

对于定义,默认参数是无关紧要的。如果你得到 5 并不重要,因为有人在调用站点明确地输入了它,或者编译器是否通过默认参数添加了它。这就是为什么当你有一个单独的声明和定义时,默认参数只对声明是必需的。您可以而且应该将其排除在定义之外。否则你必须无缘无故地在两个地方维护它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-15
    • 2014-04-15
    • 1970-01-01
    • 2020-08-02
    • 2022-10-17
    • 2023-03-12
    • 2022-07-06
    • 2012-10-05
    相关资源
    最近更新 更多