C++ const 引用默认值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14612933/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 18:30:35  来源:igfitidea点击:

const reference default-value

c++referenceconstdefault-value

提问by aiao

Possible Duplicate:
how to initialize function arguments that are classes with default value

可能的重复:
如何初始化具有默认值的类的函数参数

#include <string>

void foo1(const std::string& s = std::string());

void foo2(std::string& s = std::string());

void foo3(const std::string s = std::string());

void foo4(std::string s = std::string());

error at foo2(): default argument for ‘std::string& s' has type ‘std::string {aka std::basic_string<char>}'

error at foo2(): default argument for ‘std::string& s' has type ‘std::string {aka std::basic_string<char>}'

I understand the compiler's point, but I don't get how this does not apply to foo1()as well.

我理解编译器的观点,但我不明白这如何不适用于foo1()

回答by Bill

You can't take a non-const reference to a temporary like foo2 does.

您不能像 foo2 那样对临时对象进行非常量引用。

Notice that this isn't specifically default parameters. You get the same error for function variables: http://ideone.com/g7Tf7L

请注意,这不是专门的默认参数。对于函数变量,您会遇到相同的错误:http: //ideone.com/g7Tf7L

#include <string>
using std::string;

#include <iostream>
using std::cout; using std::endl;

int main()
{
    string s1        = string("s1"); // OK, copy it
    const string& s2 = string("s2"); // OK, const reference to it
    string& s3       = string("s3"); // ERROR! non-const reference not allowed!

    cout
            << s1 << ", "
            << s2 << ", "
            << s3 << endl;
    return 0;
}

When you take a const reference to a temporary, the lifetime of the temporary is extended to the lifetime of the reference (§12.2, quoted from my copy of C++11 draft n3337):

当您对临时对象进行 const 引用时,临时对象的生命周期会延长到引用的生命周期(第 12.2 节,引用自我的 C++11 草案 n3337 副本):

There are two contexts in which temporaries are destroyed at a different point than the end of the fullexpression.

...

The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:

  • A temporary bound to a reference member in a constructor's ctor-initializer (12.6.2) persists until the constructor exits.
  • A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression containing the call.
  • The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
  • A temporary bound to a reference in a new-initializer (5.3.4) persists until the completion of the full-expression containing the new-initializer.

在两种情况下,临时对象在与完整表达式结束不同的点被销毁。

...

第二个上下文是引用绑定到临时对象时。引用绑定到的临时对象或作为引用绑定到的子对象的完整对象的临时对象在引用的生命周期内持续存在,除了:

  • 临时绑定到构造函数的 ctor-initializer (12.6.2) 中的引用成员会一直存在,直到构造函数退出。
  • 函数调用(5.2.2)中引用参数的临时绑定一直存在,直到包含调用的完整表达式完成。
  • 函数返回语句(6.6.3)中与返回值的临时绑定的生命周期没有延长;临时在 return 语句中的完整表达式结束时被销毁。
  • 一个临时绑定到一个 new-initializer (5.3.4) 中的引用一直存在,直到包含 new-initializer 的完整表达式完成。

回答by Kerrek SB

It may come as a surprise to you, but you canbind the value of a temporary expression to a constantreference, and the lifetime of the expression is extended to that of the reference. But you cannot do this with a non-constant (lvalue) reference.

您可能会感到惊讶,但是您可以将临时表达式的值绑定到常量引用,并且表达式的生命周期会延长到引用的生命周期。但是你不能用非常量(左值)引用来做到这一点。

回答by David Hammen

The declarations of foo3and foo4are legal because the argument to those functions is not a reference.

的声明foo3foo4是合法的,因为参数的功能是不是一个引用。

The declaration of foo2is illegal because you can't bind a non-const reference to a temporary.

的声明foo2是非法的,因为您不能将非常量引用绑定到临时引用。

So why is the declaration of foo1legal? It's that very important constqualifier that makes this declaration legal.

那么为什么声明是foo1合法的呢?正是这个非常重要的const限定符使此声明合法。