Как правильно использовать std :: move (): CLion, не распознавая его? - PullRequest
0 голосов
/ 19 сентября 2018

Ниже приведен код:

template<class T> <typename my_set<T>::const_iterator, bool> 
my_set<T>::insert(const value_type &val)
    {
        // does all kinds of things
    }

template<class T>
    pair<typename my_set<T>::const_iterator, bool> my_set<T>::insert(value_type &&val)
{

    return insert(std::move(val)); // should call the func above
};

Но когда я его запускаю, он рекурсивно вызывает себя + CLion отладчик говорит: нет символа "move" в пространстве имен "std".

halp.

1 Ответ

0 голосов
/ 19 сентября 2018

Проблема в том, что std::move делает val значение ссылки снова, и вы вызываете ту же функцию рекурсивно.Если вы хотите, чтобы вторая функция вызывала первую, вам нужно передать val напрямую:

return insert(val);

Хотя не совсем понятно, зачем вам это нужно, поскольку вы добились бы того же, просто исключив вторую функцию (затем ссылку на значениебудет привязан к константной lvalue ссылке, так как лучшего совпадения нет)

Примечание: это не ясно из вашего кода, но если вы хотите, чтобы вторая функция выполняла реальное перемещение, вы ошиблись, но это распространенная ошибкахоть.std::move ничего не перемещает само по себе , оно просто меняет именованный тип объекта на ссылку-значение, а затем фактическое перемещение происходит в конструкторе перемещения или операторе присваивания перемещения класса (если они, конечно, реализованы).

Простое решение может состоять в том, чтобы просто иметь одну функцию и передавать объект по значению или использовать переадресацию или универсальную ссылку:

template<class T> std::pair<typename my_set<T>::const_iterator, bool> 
my_set<T>::insert( value_type val)
{
    ...
    internal_object = std::move( val );
    ...
}
...