ОБНОВИТЬ внизу.
Я хочу, чтобы make void tree :: operator = (tree t) использовал значение rvalue. (В этом случае, в общем, я хочу обработать их по-другому из-за эффективности)
Я кодировал его, использовал std :: move, чтобы убедиться, что он будет использовать rvalue, но компилятор говорит, что не знает, какой оператор выбрать. Разве он не должен выбрать это, используя rvalues?
Код:
void tree::operator = ( tree&& t )
{
std::swap(this->pntr, t.pntr);
}
void tree::operator = ( tree t )
{
*this = std::move(t);
}
Ошибка компилятора:
tree.cpp:23:9: error: use of overloaded operator '=' is ambiguous (with operand types 'tree' and 'typename remove_reference<tree &>::type' (aka 'tree'))
*this = std::move(t);
~~~~~ ^ ~~~~~~~~~~~~
tree.cpp:16:12: note: candidate function
void tree::operator = ( tree&& t )
^
tree.cpp:21:12: note: candidate function
void tree::operator = ( tree t )
^
1 error generated.
Я использую clang-503.0.38. (но с gcc 4.8 такая же ошибка)
ОБНОВИТЬ
Хорошо, теперь у меня есть:
tree& tree::operator = ( tree&& t )
{
std::swap(this->pntr, t.pntr);
}
tree& tree::operator = ( const tree & t )
{
*this = tree(t); // tree:tree( const tree& t )
}
И это работает. Завтра я опубликую то, что я узнал из этого, как Ответ.
Вы можете кодировать только одно дерево версий :: operator = (tree t), которое реализовано с использованием идиомы копирования и замены, в то время как предусмотрены конструктор копирования и конструктор перемещения.
Таким образом, клиент класса может выбрать назначение копирования, например:
tree1 = tree2;
, В то время как можно также выбрать назначение перемещения, например:
tree1 = std::move(tree2);
У вашего кода есть несколько проблем:
Оператор присваивания должен возвращать ссылку на сам объект. То есть должен вернуться tree&
не void
,
И то и другое tree::operator=( tree other )
а также tree::ooperator( tree&& other )
может принимать значения, таким образом, перегрузки неоднозначны. Если вам нужно / нужно только присвоение rvalue, то ваше присвоение rvalue, основанное на копировании и обмене, является правильным, но если вам нужны и значения rvalue, и значения lvalue Вы должны предоставить только по значению присвоения и использовать копию и заменить его на него:
tree& tree::operator=( tree other )
{
using std::swap; //Enable ADL (Not strictly neccesary, but good practice)
swap( *this , other );
return *this;
}
Обратите внимание, что вы должны написать кастом swap()
функция, чтобы сломать потенциальную бесконечную рекурсию на std::swap()
реализация по умолчанию. Читать эта тема для более подробного рассмотрения идиомы копирования и обмена.