Является ли std :: move (* this) хорошим шаблоном?
Чтобы заставить этот код с C ++ 11 ссылочными квалификаторами работать как положено, я должен представитьstd::move(*this)
это не звучит правильно.
#include<iostream>
struct A{
void gun() const&{std::cout << "gun const&" << std::endl;}
void gun() &&{std::cout << "gun&&" << std::endl;}
void fun() const&{gun();}
void fun() &&{std::move(*this).gun();} // <-- is this correct? or is there a better option
};
int main(){
A a; a.fun(); // prints gun const&
A().fun(); // prints gun&&
}
Что-то не звучит правильно об этом.Этоstd::move
необходимо? Это рекомендуемое использование для этого? На данный момент, если я не использую его, я получаюgun const&
в обоих случаях это не ожидаемый результат.
(Кажется, что*this
неявная и lvalue ссылка всегда, что имеет смысл, но тогда единственный способ избежать использованияmove
)
Протестировано сclang 3.4
а такжеgcc 4.8.3
.
РЕДАКТИРОВАТЬЭто то, что я понимаю из ответа @hvd:
1)std::move(*this)
синтаксически и концептуально правильно
2) Однако, еслиgun
не является частью желаемого интерфейса, нет причин перегружать его версиями lv-ref и rv-ref. И две функции с разными именами могут выполнять одну и ту же работу. В конце концов, ref-определители имеют значение на уровне интерфейса, который обычно является только публичной частью.
struct A{
private:
void gun() const{std::cout << "gun const&" << std::endl;}
void gun_rv(){std::cout << "gun called from fun&&" << std::endl;}
public:
void fun() const&{gun();}
void fun() &&{gun_rv();} // no need for `std::move(*this)`.
};
Но опять же, еслиgun
является частью (общего) интерфейса, тоstd::move(*this)
необходимо, но только тогда. А также, даже еслиgun
не является частью интерфейса есть преимущества читабельности в том, чтобы не разбивать функциюgun
как две по-разному названные функции и стоимость этого, ну ...,std::move(*this)
.
РЕДАКТИРОВАТЬ 2: В ретроспективе это похоже на случай C ++ 98const
и нет-const
перегрузка той же функции. Внекоторые случаи имеет смысл использоватьconst_cast
(другая форма приведения), чтобы не повторять код и иметь две функции с одинаковым именем ...РЕДАКТИРОВАТЬ 3: ...https://stackoverflow.com/a/124209/225186