[解決済み] 関数からunique_ptrを返す
質問
unique_ptr<T>
はコピー構築を許可せず、代わりに移動セマンティクスをサポートします。しかし、私は
unique_ptr<T>
関数から返された値を変数に代入しています。
#include <iostream>
#include <memory>
using namespace std;
unique_ptr<int> foo()
{
unique_ptr<int> p( new int(10) );
return p; // 1
//return move( p ); // 2
}
int main()
{
unique_ptr<int> p = foo();
cout << *p << endl;
return 0;
}
上のコードはコンパイルして意図したとおりに動作します。では、どうして
1
がコピーコンストラクタを呼び出してコンパイラーエラーになることはないのでしょうか?もし、私が行
2
を使うのは理にかなっていると思います。
2
も同様に動作しますが、そうする必要はありません)。
C++0xではこの例外を認めていますが
unique_ptr
というのも、戻り値は一時的なオブジェクトであり、関数が終了すると同時に破棄されるため、戻り値のポインタの一意性が保証されるからです。これはどのように実装されているのか気になります。コンパイラで特別にケース分けされているのか、それとも言語仕様に何か他の条項があり、これを悪用しているのでしょうか?
解決方法は?
<ブロッククオートは、言語仕様の他の条項を悪用したものなのでしょうか?
はい、12.8 §34 と §35 を参照してください。
特定の条件を満たした場合、実装はクラスオブジェクトのコピー/移動の構築を省略することが許される[...]。 このコピー/移動操作の省略は、以下のように呼ばれる。 コピーエリジョン が許可される[...]。 は、クラスの戻り値の型を持つ関数の return 文で許可されています。 の名前である場合、その式は 不揮発性自動オブジェクト 関数の戻り値の型と同じ cv-unqualified 型の [...]...
コピー操作のエリシオン条件を満たし、コピーされるオブジェクトがlvalueで指定されている場合。 コピー先のコンストラクタを選択するための過負荷解消が最初に行われます。 オブジェクトがr値で指定されている場合と同じように .
最悪の場合、つまりC++11、C++14、C++17でエリジオンを使用しない場合、return文の名前付き値はrvalueとして扱われるため、ここでは値で返すことがデフォルトの選択であることをもう一点だけ付け加えたいと思います。 したがって、たとえば次のような関数は
-fno-elide-constructors
フラグ
std::unique_ptr<int> get_unique() {
auto ptr = std::unique_ptr<int>{new int{2}}; // <- 1
return ptr; // <- 2, moved into the to be returned unique_ptr
}
...
auto int_uptr = get_unique(); // <- 3
コンパイル時にフラグを立てると、この関数内で2手(1、2)が発生し、その後に1手(3)が発生します。
関連
-
[解決済み】コンストラクターでのエラー:識別子を期待されますか?
-
[解決済み] [Solved] Error C1083: Cannot open include file: 'stdafx.h'
-
[解決済み】C++でランダムな2倍数を生成する
-
[解決済み】変数 '' を抽象型 '' と宣言できない。
-
[解決済み] クラスにデフォルトコンストラクタが存在しない。
-
[解決済み】C++エラー:の初期化に一致するコンストラクタがありません。
-
[解決済み] 式はクラス型を持つ必要があります。
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み] C++で仮想関数が必要な理由とは?
-
[解決済み] コンストラクタや関数に unique_ptr 引数を渡すにはどうしたらいいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] テスト
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み】C++のGetlineの問題(オーバーロードされた関数 "getline "のインスタンスがない
-
[解決済み】C++エラーです。"配列は中括弧で囲まれたイニシャライザーで初期化する必要がある"
-
[解決済み] string does not name a type Errorが発生するのはなぜですか?
-
[解決済み】変数 '' を抽象型 '' と宣言できない。
-
[解決済み】C++の変数はイニシャライザーを持っているが、不完全な型?
-
[解決済み】エラー:strcpyがこのスコープで宣言されていない
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み] 警告:暗黙の定数変換でのオーバーフロー