Почему RVO не работает с конструктором перемещения?

Я пытаюсь проверить РВО а также Rvalue ссылка. Вот код:

#include <iostream>

using namespace std;

class B{
public:
int i;

B(){
i = 0;
cout << "B() " << i << endl;
}

B(const B& b){
i = 1;
cout << "B(const B&) " << i << endl;
}

B(const B&& b){//if remove this constructor, then call B(const B& b)
i = 2;
cout << "B(const B&&) " << i << endl;
}

~B(){
cout << "~B() " << i << endl;
}
};

B f(){
B b;
return b;
}

int main(){

B b = f();

return 0;
}

Выход:

B() 0
B(const B&&) 2
~B() 0
~B() 2

Среда: WIN8, Visual Studio 2012 Express

Это означает, что переместить конструктор: B (const B&&) называется.
Подняты два вопроса:

  • Зачем РВО здесь не применяется?
  • Зачем НЕ позвонить конструктор копирования: B (const B&)?
  • Если я удалю B (const B&&), затем B (const B&) называется. Странный вывод:

    B () 0
    B (const B&) 1
    ~ B () 0
    ~ B () 1

Вот ссылки, которые я нашел:


РЕДАКТИРОВАТЬ:
переместить конструктор должно быть B (B&&). Дело в том, почему конструктор перемещения называется НЕ конструктор копирования.

0

Решение

Почему РВО здесь не применяется?

Это не просто выполнение оптимизаций. G ++ использует RVO здесь при использовании -O2, Вы должны включить оптимизацию на вашем компиляторе, чтобы проверить это. Однако обратите внимание, что даже если некоторые компиляторы могут применять RVO, это не обязательно, поэтому вы можете увидеть разные результаты при использовании разных компиляторов.

Почему НЕ вызывать конструктор перемещения: B (const B&)?

Это конструктор копирования. Он вызывает конструктор перемещения, который здесь лучше подходит.

Если я удаляю B (const B&&), то B (const B&) называется. Weird!

Нет, это не странно. Конструктор перемещения не будет неявно определен компилятором, если вы определите конструктор копирования. Следовательно, компилятор выбирает конструктор копирования, поскольку конструктор перемещения недоступен.

Обратите внимание, что ваш конструктор перемещения должен иметь неконстантную ссылку:

B(B&& b) {
// ...
}

В противном случае вы бы просто сделали то же самое, что и в конструкторе копирования.

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]