在C++中,我们可以将对象分配给非const引用。所以这有效:

Foo &foo = Foo();

但是,C++不允许将临时变量分配给非const引用。因此,这是不允许的:
Bar::Bar(Foo &foo = Foo()) {}

但这是允许的
Bar::Bar(const Foo &foo = Foo()) {}

我在这里有三个问题:
  • 在最后一种情况下foo的作用域是什么?即使退出构造函数后,它仍然存在吗?根据我的阅读,如果将临时对象分配给const引用,则会修改其生存期,在这种情况下,它将占用分配给它的引用的生存期。默认参数(在这种情况下为foo)的生存期是多少?
  • 我在MSVC中尝试了第二个示例,但它没有抱怨。我还注意到,临时文件的寿命仍在延长。因此,我可以在构造函数退出后使用foo。那是什么意思
  • 我的场景要求以这种方式将默认参数传递给构造函数,而我将需要在构造函数中修改该参数(因此无法将其设为const)。而且我还需要在构造函数退出后使用foo。什么是最适合这种情况的设计?

  • 提前致谢。

    最佳答案


    foo是一个构造函数(同样适用于常规函数)参数,因此其生存期在the full expression containing the call to the constructor ends时结束。谢谢aschepler!



    通过将默认参数绑定(bind)到Foo const& foo可以延长默认参数的生存期,因此默认参数的生存期将与其绑定(bind)的引用的生存期相匹配,即直到构造函数主体退出。



    如果将警告级别设置为/W4,它将执行此操作;在这种情况下,它会警告您正在使用非标准扩展名。 AFAIK,语义与前面的情况相同。



    这取决于您是否要将其保存为Bar的成员。如果是前者,请使用右值引用并移动参数

    Bar::Bar(Foo&& foo = Foo()) : f_(std::move(foo)) {} // f_ is a member of type Foo
    

    否则,只需忽略默认参数即可。您还可以创建两个重载来覆盖不同的情况。

    关于c++ - 在构造函数中使用临时作为默认参数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22258792/

    10-11 22:37
    查看更多