web-dev-qa-db-ja.com

const referencedefault-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>}’

コンパイラのポイントは理解していますが、これがfoo1()にも当てはまらない方法がわかりません。

16
aiao

Foo2のように、一時的なものへの非const参照を取得することはできません。

これは特にデフォルトのパラメータではないことに注意してください。関数変数についても同じエラーが発生します: 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;
}

一時的なものへのconst参照を取得すると、一時的なものの有効期間は参照の有効期間まで延長されます(§12.2、C++ 11ドラフトn3337の私のコピーから引用):

完全表現の終わりとは異なる時点で一時変数が破棄される2つのコンテキストがあります。

.。

2番目のコンテキストは、参照が一時的なものにバインドされている場合です。参照がバインドされている一時オブジェクト、または参照がバインドされているサブオブジェクトの完全なオブジェクトである一時オブジェクトは、次の場合を除いて、参照の存続期間中存続します。

  • コンストラクターのctor-initializer(12.6.2)の参照メンバーへの一時的なバインドは、コンストラクターが終了するまで存続します。
  • 関数呼び出し(5.2.2)の参照パラメーターへの一時的なバインドは、呼び出しを含む完全な式が完了するまで持続します。
  • 関数returnステートメント(6.6.3)の戻り値に一時的にバインドされている期間は延長されません。一時は、returnステートメントの完全な式の最後で破棄されます。
  • New-initializer(5.3.4)内の参照への一時的なバインドは、new-initializerを含む完全な式が完了するまで持続します。
24
Bill

意外かもしれませんが、can一時式の値をconstant参照にバインドすると、式の有効期間が参照。ただし、非定数(左辺値)参照ではこれを行うことはできません。

3
Kerrek SB

foo3およびfoo4の宣言は、これらの関数への引数が参照ではないため、正当です。

foo2の宣言は、非const参照を一時参照にバインドできないため、不正です。

では、なぜfoo1の宣言が合法なのですか?この宣言を合法にするのは、非常に重要なconst修飾子です。

0
David Hammen