2017-08-03 4 views
2

をスキップ:私が使用して(私には奇妙に思えるいくつかの行動を説明するために私を助けてください私は以下のように4つのコンストラクタを持つクラス、および機能を持っているコンストラクタは、関数呼び出しとして解釈され、移動コンストラクタはstrangly

using namespace std; 

class ABC { 
public: 
    ABC() { 
     cout << "ABC()\n"; 
    } 

    ABC(int) { 
     cout << "ABC(int)\n"; 
    } 

    ABC(ABC&) { 
     cout << "ABC(&)\n"; 
    } 

    ABC(ABC&&) { 
     cout << "ABC(&&)\n"; 
    } 
}; 


void ff(ABC t) { } 

MSVC 2016をコンパイルするには):

1)なぜ、私はCBC301の "ABC a1(ABC(__cdecl *)(void))":プロトタイプ関数が呼び出されていない次のコード:

void main() { 
    ABC a1(ABC()); 
    ff(ABC(5)); 
} 

と実行時に、私は次のような出力を得ることを期待:私は本当に取得

ABC() 
ABC(&&) 
ABC(int) 
ABC(&&) 

が、何が、私はそこにある

void main() { 
    ABC a1(ABC(5)); 
    ff(ABC(5)); 
} 

に変更する今場合

ABC(int) 

2)でありますこれ以上の警告はありません。しかし、実行時に、私は何を得ることを期待することは

ABC(int) 
ABC(&&) 
ABC(int) 
ABC(&&) 

ですが、私が実際に取得することは

ABC(int) 
ABC(int) 

3である)今

void main() { 
    ABC(ABC()); 
    ff(ABC(5)); 
} 

それも、コンパイルされません。私はエラーC2660: "'ABC':関数は1つの引数を取ることはありません。

4)最後に、なぜ3)はコンパイルしないのですか?

void main() { 
    ff(ABC(5)); 
} 
+2

問題の一部:https://stackoverflow.com/questions/38951362/most-vexing-parse – NathanOliver

+4

1と2のコードスニペットはまったく同じです。そして、 'int main()'でなく 'void 'でなければなりません。 – Slava

+1

C++ 11以降を使用していますか? –

答えて

5

によりmost vexing parse in C++として知られている問題に、ライン

ABC a1(ABC()); 

は、その戻り型ABCと引数型引数及び戻りをとらない関数である関数であることを宣言しa1ABC


ABC(ABC()); 

は解剖が困難であるが、それはまた、関数の宣言ではなく、変数の定義です。

int(a); 

は、変数aの有効な宣言です。意味をオーバーロードしています。ここ

ABC ABC(); 

ABC

int a; 

同様に、ABCとラインが同じである:同じです。最初のABCが型名です。2番目のABCは関数名です(最も厄介な解析のため)。 ABCは、引数を取らずにタイプABCのオブジェクトを返す関数であると宣言します。関数の残りの部分では、ABCが関数名であり、型名ではありません。その文脈でABCが引数をとらない関数であるので、その結果、

ff(ABC(5)); 

は無効です。


移動コンストラクタが呼び出されない理由についての回答はありません。

+1

2番目の問題は、OPの誤って1と同じコードを使用しているようです。私はそれがABC a1(ABC(5));であると推測しています – Slava

+1

OPはなぜctorを移動するための呼び出しが欠落しているかを尋ねます。 – Slava

+0

私は肯定的ではありませんが、効率的な目的でコンパイラに除外するオプションがあるため、移動コンストラクタは呼び出されないと思います。 – Andy

関連する問題