2016-09-16 8 views
0

関数内のすべてのローカル変数にautoを使用しようとしています。C++:関数を使ってクラスを変数として宣言する

次のコードください:コードをコンパイルする

class obj 
{ 
    public: 
    obj() {}; 
    obj(obj&& o) = delete; 
}; 

int main() 
{ 
    obj test0; 
    auto test1 = obj(); 

    return 0; 
} 

:TEST0を定義することは完全に大丈夫ですが、TEST1の宣言の正確な同じ種類を行うにしようとすると、コンパイラであることを

$ g++ --std=c++1z main.cpp 
main.cpp: In function ‘int main()’: 
main.cpp:13:20: error: use of deleted function ‘obj::obj(obj&&)’ 
    auto test1 = obj(); 

お知らせエラー。明らかにコンパイラエラーであるべきですが、この場合、objをautoで定義することはできませんか?私は制御できないQTオブジェクトでこの問題に取り組んでいます。

変数を宣言するためにC++ 98形式を使用していますか、またはautoを使用する別の方法はありますか?

ありがとうございました!それは右辺値であるとして宣言

auto test1 = obj(); 

+1

'auto test1 = obj();'では、 "コピー初期化"を使用しています。しかし、 'obj'は、コピーコンストラクタ(コピーコンストラクタの宣言、コピーコンストラクタの暗黙的生成の防止)、コンストラクタブル(削除可能と宣言されている)のどちらでもありません。 – KABoissonneault

+0

今後このようなトラップを防ぐには、C++の "Rule of 5"を使用することを検討してください – KABoissonneault

+0

ありがとう、私は何が起こっているのか理解できていません。私の質問は、このようなクラスで自動的に使用できますか?もしそうなら。 –

答えて

5

これはC++ 17ではOKです。保証されたコピーのelisionは、ムーブコンストラクタが概念的に呼び出されないようにルールを調整するので、削除されているかアクセスできないかは関係ありません。

そんなにautoを愛していれば、その後、あなたは

auto&& test1 = obj(); 

を行うことができます前に、これは一時的なobjオブジェクトを作成し、参照のそれにその寿命を延長し、参照test1にバインドします。例外はいくつかありますが、その動作はC++で得られるものとほとんど同じです。auto

+0

rvalue参照は 'const auto&'と同じ方法で一時ファイルの有効期間を延長しますか? – KABoissonneault

+0

@KABoissonneaultはい。 –

+0

ああ男の子!私はちょうどそれを試して、これは動作します。まさに私が探していたもの。削除されたメソッドが呼び出されない理由を説明する代わりに、実際に質問を読んでくれてありがとう! –

3

コンパイラは、RHS上のオブジェクトを移動しようとします。それはできません(移動先が削除済みとしてマークされているため)。コンパイラは移動を試みるだけですが(移動先は削除されていても、まだユーザ定義であり、it is selected as a candidate during overload resolutionと考えられます)、移動先が削除されるため、コピー先も削除されることに注意してください。したがって、コードはコンパイルされません。

+0

ありがとう、私は正確に何をして、私の質問は、この場合は変数test1を宣言するために使用することができますか? –

+1

'auto'宣言はうまくいき、コンパイルの失敗とは関係ありません。 –

3

エラーは特にautoの使用とは関係ありません。

obj test1 = obj(); 

もコンパイルされません。 obj()はr値であり、コンパイラは移動しようとしますが、移動コンストラクタは削除されます。移動コンストラクタを削除すると、コンパイラはコピーコンストラクタを作成することもできないため、コピーコンストラクタも作成できません。そのため、エラーも発生します。

関連する問題