Why in C ++ 0x does the compiler choose the general purpose of the transition for a particular one?

I have the following code:

#include <iostream>
using namespace std;

template <class T> class Foo {
public:
    template <class U> void operator = (const U &u) {
        cout << "generic copy assigment\n";
    }

    void operator = (const Foo<T> &f) {
        cout << "specific copy assigment\n";
    }

    template <class U> void operator = (U &&u) {
        cout << "generic move assigment\n";
    }

    void operator = (Foo<T> &&f) {
        cout << "specific move assigment\n";
    }
};

int main() {
    Foo<int> i, j;
    i = j;
    return 0;
}

If this is done, it prints a "general purpose transfer", that is, the compiler prefers moving around the copy. However, if I comment on two transfer destinations:

template <class T> class Foo {
public:
    template <class U> void operator = (const U &u) {
        cout << "generic copy assigment\n";
    }

    void operator = (const Foo<T> &f) {
        cout << "specific copy assigment\n";
    }
};

the conclusion is "the purpose of a specific copy."

In other words, when a class is included with the ability to move, the general transition is selected according to a certain one, whereas if the class is not included, a specific copy is selected according to the general version.

Is this a Visual Studio 2010 bug, or is this behavior defined in the C ++ 0x specs?

+3
source share
2 answers

" ". " ", , . ++ 0x , "T & &" : Lvalue T ArgType&, Rvalue ArgType. , lvalue ArgType ArgType&, Rvalue ArgType&&.

lvalue "Foo &", lvalue.

(n3126) ( ). issue 1080, .

+5
#include <iostream>
using namespace std;

template <class T> class Foo {
    public:
    template <class U> void operator = (const U &u) {
        cout << "generic copy assigment\n";
    }

    void operator = (const Foo<T> &f) {
        cout << "specific copy assigment\n";
    }

    template <class U> void operator = (U &&u) {
        cout << "generic move assigment\n";
    }

//    void operator = (Foo<T> &&f) {
//        cout << "specific move assigment\n";
//    }
};

int main() {
    Foo<int> i, j;
    i = std::move(j);
    return 0;
}
0

Source: https://habr.com/ru/post/1773235/


All Articles