C ++ 11 неоднозначная ошибка с двумя операторами (один lvalue второй rvalue)

ОБНОВИТЬ внизу.

Я хочу, чтобы 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 )
}

И это работает. Завтра я опубликую то, что я узнал из этого, как Ответ.

2

Решение

Вы можете кодировать только одно дерево версий :: operator = (tree t), которое реализовано с использованием идиомы копирования и замены, в то время как предусмотрены конструктор копирования и конструктор перемещения.

Таким образом, клиент класса может выбрать назначение копирования, например:

tree1 = tree2;

, В то время как можно также выбрать назначение перемещения, например:

tree1 = std::move(tree2);
3

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

У вашего кода есть несколько проблем:

  • Оператор присваивания должен возвращать ссылку на сам объект. То есть должен вернуться 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() реализация по умолчанию. Читать эта тема для более подробного рассмотрения идиомы копирования и обмена.

2

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