c ++: operator = является неоднозначным при реализации назначения перемещения - PullRequest
0 голосов
/ 06 декабря 2018

Я пытаюсь реализовать правило пяти впервые.Прочитав много рекомендаций о передовых практиках, я в итоге нашел решение, в котором операторы копирования / перемещения, по-видимому, находятся в некотором конфликте.

Вот мой код.

#include <vector>   
#include <memory>

template<class T> class DirectedGraph {
public:
    std::vector<T> nodes;
    DirectedGraph() {}
    DirectedGraph(std::size_t n) : nodes(n, T()) {}
    // ... Additional methods ....
};

template<class T>
DirectedGraph<T> Clone(DirectedGraph<T> graph) {
    auto clone = DirectedGraph<T>();
    clone.nodes = graph.nodes;
    return clone;
}

template<class T> class UndirectedGraph
{
    using TDirectedG = DirectedGraph<T>;
    using TUndirectedG = UndirectedGraph<T>;

    std::size_t numberOfEdges;
    std::unique_ptr<TDirectedG> directedGraph;
public:
    UndirectedGraph(std::size_t n)
        : directedGraph(std::make_unique<TDirectedG>(n))
        , numberOfEdges(0) {}

    UndirectedGraph(TUndirectedG&& other) {
        this->numberOfEdges = other.numberOfEdges;
        this->directedGraph = std::move(other.directedGraph);
    }

    UndirectedGraph(const TUndirectedG& other) {
        this->numberOfEdges = other.numberOfEdges;
        this->directedGraph = std::make_unique<TDirectedG>
            (Clone<T>(*other.directedGraph));
    }

    friend void swap(TUndirectedG& first, TUndirectedG& second) {
        using std::swap;
        swap(first.numberOfEdges, second.numberOfEdges);
        swap(first.directedGraph, second.directedGraph);
    }

    TUndirectedG& operator=(TUndirectedG other) {
        swap(*this, other);
        return *this;
    }

    TUndirectedG& operator=(TUndirectedG&& other) {
        swap(*this, other);
        return *this;
    }

    ~UndirectedGraph() {}
};

int main()
{
    UndirectedGraph<int> graph(10);
    auto copyGraph = UndirectedGraph<int>(graph);
    auto newGraph = UndirectedGraph<int>(3);
    newGraph = graph;            // This works.
    newGraph = std::move(graph); // Error here!!!
    return 0;
}

Большинствоиз рекомендаций, которые я взял из здесь , и я реализовал назначение копирования operator=, чтобы принять параметр по значению .Я думаю, что это может быть проблемой, но я не понимаю, почему.

Кроме того, я был бы очень признателен, если бы кто-то указал, правильно ли реализованы мои копии / перемещение ctor / assignments.

1 Ответ

0 голосов
/ 06 декабря 2018

Вы должны иметь:

TUndirectedG& operator=(const TUndirectedG&);
TUndirectedG& operator=(TUndirectedG&&);

или

TUndirectedG& operator=(TUndirectedG);

Наличие обоих

TUndirectedG& operator=(TUndirectedG);   // Lead to ambiguous call
TUndirectedG& operator=(TUndirectedG&&); // Lead to ambiguous call

приведет к неоднозначному вызову с rvalue.

...