Search code examples
c++c++11move

The value gets copied instead of being moved. Why?


Why do objects declared here are not being moved, but copied instead? Is it somehow related with copy elision? Shouldn't current code have changed class' objects? It was initially expected that by using std::move the internals of B would have been changed. Did I overlook something? Is there any workaround?

#include <iostream>
#include <algorithm>
#include <vector>

class A {
    public:
        A() {}
        auto&& get() { return v; }
        friend std::ostream& operator<<(std::ostream& o, A const& a) {
            o << "A: ";
            for (auto it = std::begin(a.v); it != std::end(a.v); ++it) { if (it != std::begin(a.v)) { o << " "; } o << *it; }
            return o;
        }
    private:
        std::vector<int> v;
};

class B {
    public:
        B() {};
        auto&& get() { return v; }
        friend std::ostream& operator<<(std::ostream& o, B const& b) {
            o << "B: { ";
            for (auto it = std::begin(b.v); it != std::end(b.v); ++it) { if (it != std::begin(b.v)) { o << " } { "; } o << *it; }
            return o << " }";
        }
    private:
        std::vector<A> v;
};

int main() {
    A a, a1, a2; B b;

    a.get().insert(a.get().end(), {1, 2, 3, 4});
    a1.get().insert(a1.get().end(), {5, 6, 7, 8});
    a2.get().insert(a2.get().end(), {9, 10, 11, 12});

    std::cout << a << "\n" << a1 <<  "\n" << a2;
    b.get().insert(b.get().end(), {a, a1, a2});
    std::cout << "\n" <<  b << "\n";

    a.get().push_back(std::move(b.get()[2].get()[2])); 

    std::cout << a << "\n" << a1 <<  "\n" << a2;
    std::cout << "\n" <<  b;
    return 0;
}

Solution

  • You're calling std::move on an int. For non-class types, copying and moving are identical operations.