必须非常量别名参数及其默认参数常量

must-non constant alias argument with its default argument constant

本文关键字:常量 参数 默认 别名 非常      更新时间:2023-10-16

我们如何编写一个必须非常量别名参数,其默认参数必须是常量,因为它无法引用?
并且必须没有过载功能,因为它有 91 行长

Bar {
int on;
Bar(){};
Bar(bool o): off{o}{}
bool off; 
}
int fooBar(int board, Bar& bar = static_cast<Bar>(1)) {
//...
}

海湾合作委员会给了

错误:无法将类型为"Bar&"的非常量左值引用绑定到 类型为"条形"的右值

如何解决 - 有明确的解释 - 这种?

您收到此错误的原因是,正如您发现的那样,非const引用必须绑定到左值:也就是说,它必须绑定到具有名称的对象。临时不会绑定到非const引用:只会绑定到const Bar&Bar&&,两者都不是你想要的。

这给我们留下了几个选择。

我个人最喜欢的是根本不使用默认参数,而是提供一个重载:

int fooBar(int board, Bar& bar) {
// ...
}
int fooBar(int board) {
// to save code duplication you can call in fooBar
Bar b{1};
return fooBar(board, b);
}

在我看来,这是最简单,最一致的选择。

其他可能性包括:

创建一个全局变量,其
  • 唯一目的是成为默认参数(yuck,并干扰多线程(:
    inline Bar default_bar;
    int fooBar(int board, Bar& bar = default_bar) {
    // ...
    }
    
  • 改用指针,但需要注意的是,您必须检查它们是否提供了参数:
    int fooBar(int board, Bar* bar = nullptr) {
    // ..., but make sure to test bar!
    }
    
  • 或以其他方式使用std::optional<std::reference_wrapper<Bar>>或类似类型。

您可以定义这样的帮助程序函数:

template <typename Ty> Ty &make_ref(const Ty &cref)
{
return const_cast<Ty&>(cref);
}

然后按如下方式使用它:

int fooBar(int board, Bar& bar = make_ref(Bar(1))) {
//...
}