0

I was reading about std::move. Based on quite few materials, I concluded that std::move is just a function that converts its argument type to the rvalue-reference.

I also read that, rvalue-references can be used with the functions that take their arguments as const-references. This is meaningful because the contents of the objects guaranteed to be not changed.

To verify these ideas, I made a very simple experiment with a class located below.

I have created an object t1 and used std::move to convert it to rvalue-reference and tried to create another object t2 with calling copy-constructor.

The mysterious part is that even if I don't provide move-constructor, it works with the copy-constructor which I intentially defined its parameter as non-const reference.

However, if std::move converts type of t1 to rvalue-reference, how compiler can bind it to the lvalue-reference?

Btw, I am using "Microsoft (R) Microsoft Visual Studio 2012 Version 11.0.50727.1".

Could you please explain what I am missing here?

Thank you very much.

#include <iostream>
#include <algorithm>

using namespace std;

class Trace {
    public:
        Trace() {
        }

        // @1
        Trace(Trace& t) {
            cout << "trace::trace(&)" << endl;
        }

        // @2
        Trace(Trace&& t) {
            cout << "trace::trace(&&)" << endl;
        }
};

int main(int argc, const char *argv[])
{
    Trace t1;

    // Calls @2 if it exists, otherwise calls @1 
    Trace t2(std::move(t1));
    return 0;
}
Validus Oculus
  • 2,756
  • 1
  • 25
  • 34
  • 5
    MSVC lets you bind rvalue expressions to non-const lvalue references, this is a non-conforming *feature* – Piotr Skotnicki Aug 13 '15 at 07:13
  • 2
    time to switch to a better compiler… – The Paramagnetic Croissant Aug 13 '15 at 07:15
  • "std::move is just a function that converts its argument type to the *rvalue-reference*" is true, but not useful for learning. A more useful statement would be "`std::move` unconditionally turns anything into an **rvalue**." –  Aug 13 '15 at 07:17
  • @NickyC into an *xvalue* to be pedantic – Piotr Skotnicki Aug 13 '15 at 07:18
  • @PiotrSkotnicki That's true and useful, but confusing and... pedantic. –  Aug 13 '15 at 07:20
  • 4
    @TheParamagneticCroissant gcc, clang and MSVC all have their fair share of weird behaviour in language modes that enable extensions. And for all of them, the default is to allow extensions. For MSVC, `/Za` to deactivate language extensions, but there unfortunately are more flags that influence the non-standard behaviour. – dyp Aug 13 '15 at 07:20
  • 1
    @TheParamagneticCroissant, Thanks, with /Za flag, above code causes compile time error now. – Validus Oculus Aug 13 '15 at 07:29
  • @PiotrSkotnicki Thanks, with your clue, I have found a similar problem here http://stackoverflow.com/questions/11508607/rvalue-to-lvalue-conversion-visual-studio – Validus Oculus Aug 13 '15 at 07:29
  • This code definitely is not standard conforming and should not compile. – Elohim Meth Aug 13 '15 at 07:29

0 Answers0