【问题标题】:Why are my default parameters being ignored? [duplicate]为什么我的默认参数被忽略? [复制]
【发布时间】:2018-03-26 00:32:44
【问题描述】:

为什么我的默认/可选参数被忽略了?

grid_model.h

class GridModel {
public:
        GridModel();
        void PrintGrid(bool);
};

grid_model.cpp

void GridModel::PrintGrid(bool flag = false) {
    // things...
}

grid_model_test.cpp

ns::GridModel* gm = new GridModel();
gm->PrintGrid(true); // works
gm->PrintGrid(); // doesn't work

错误:

grid_model_test.cpp:22:12: error: no matching function for call to ‘ns::GridModel::PrintGrid()’
  gm->PrintGrid();
                 ^
In file included from grid_model_test.cpp:2:0:
grid_model.h:27:7: note: candidate: void ns::GridModel::PrintGrid(bool)
  void PrintGrid(bool);
       ^~~~~~~~~

当我在其他地方使用它们时,它们似乎工作正常。

#include <iostream>

class Thing {
public:
        void Whatever(bool);
};

void Thing::Whatever(bool flag = false) {
        std::cout << "Parameter was: " << flag << std::endl;
}

int main() {
        Thing* thing = new Thing();
        thing->Whatever();
        return 0;
}

【问题讨论】:

  • 如果测试代码只看到header,它不会知道默认参数。
  • 虽然我不认为这是一个坏问题,但我认为你可以稍微改进它,但要提到它在声明和定义出现在单独的文件中时不起作用,但在它们时起作用'重新在同一个文件中(因为这在您的两种情况下有所不同)。当然,您可能没有意识到这是问题所在,在这种情况下,您可以保持原样。一个轻微的改进是删除= new,只使用更简单和正确的代码(即Thing t; t.Whatever();)。

标签: c++ optional-parameters


【解决方案1】:

作为一种良好的设计实践,默认参数值应该放在声明中,而不是在实现中:

class GridModel {
public:
        GridModel();
        void PrintGrid(bool flag=false);
};

void GridModel::PrintGrid(bool flag) {
    // things...
}

技术上(如http://en.cppreference.com/w/cpp/language/default_arguments 中的更多长度所述):默认参数必须在进行调用的翻译单元中可见。如果您在 grid_model.h 和 grid_model.cpp 中拆分类,则包含 grid_model.h 的任何其他 .cpp(例如 grid_model_test.cpp)都不会知道仅存在于 grid_model.cpp 中的信息。

【讨论】:

  • 虽然在提到的副本中有所提及,但可能值得一提的是为什么它在第二个示例中有效,但在第一个示例中无效。
  • 我编辑了答案以澄清它,谢谢。
猜你喜欢
  • 2020-04-11
  • 2011-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-10
  • 2021-01-12
  • 1970-01-01
相关资源
最近更新 更多