2016-09-01 7 views
1

ここで、creator()は、私が逆参照してfooに渡すXへのポインタを返します。それは右辺値なので、移動セマンティクスを使用する必要があります。しかし、私はそれを実行すると、私はfoo(X &)が呼び出されることがわかります。C++:foo(X &&)の代わりにfoo(X&)が呼び出されるのはなぜですか?

#include <iostream> 
using namespace std; 

struct X { 
     int i; 
}; 

void foo(X& x) { 
     cout << "foo(X&)" << endl; 
} 

void foo(X&& x) { 
     cout << "foo(X&&)" << endl; 
} 

struct X* creator() { 
     return new X {5}; 
} 

main() { 
     X x{5}; 
     foo(*creator()); // prints foo(X&) 
} 
+1

http://en.cppreference.com/w/cpp/language/operator_member_access#Built-in_indirection_operator – chris

答えて

3

creator()はポインタを返します。

ポインタを参照解除すると、左辺値が得られます。ポインタ逆参照は左辺値になります。結局、pがポインタの場合は、*p=some_valueに割り当てることができ、左辺値にのみ割り当てることができるため、左辺値でなければなりません。

あなたは2つのことで混乱しています。関数がrvalueを返すのは事実です。しかし、あなたは関数が返すものを渡すことはありません。この関数はポインタを返し、ポインタを逆参照して、左辺値を返します。

+0

私は参照してください。 std :: moveを使うと、 – user1299784

+1

* "とlvalueにしか割り当てることができないので、左辺値でなければなりません" * - これはクラスの型には当てはまりません。 –

+0

またはconstポインタ。 – Barry

3

それはアイデンティティと可動性の観点で物事を考えると便利です:

  • はアイデンティティを持ってから移動することはできませんか?左値
  • アイデンティティがあり、そこから移動できますか? xvalue
  • アイデンティティはありませんか? prvalue

ポインタを逆参照すると、移動できないIDがある式が生成されるため、左辺です。したがって、それはX&過負荷に一致します。

他のオーバーロードを呼び出す場合は、式を注釈して移動しても安全であることを示す必要があります。これは、std::moveが対象です。これを実行すると、式はxvalueになり、今度はX&&のオーバーロードに一致します。

関連する問題