mardi 18 juin 2019

Safety of auto when std::move ing from a returned reference of a value

I need some reassurance about whenever, assigning or list initializing an auto typed named variable, with

  • A a std::move()ed returned reference to a variable
  • B a returned reference to a variable

where after the expression, the origin gets out of scope, is A safe / B unsafe. Example code:

#include <iostream>
#include <string>
#include <deque>
#include <utility>

int main() {
    std::deque<std::string> container {"foo"};
    auto elementA = std::move(container.front());//A I assume this is safe
    auto elementB = container.front(); //B I assume this is unsafe
    container.pop_front();

    std::cout << "A: " << elementA << " B: " << elementB  << "\n";
}

As far as I understand expression B generates a lvalue right of the assignment and so the type of elementB is a lvalue reference aka std::string& and so that one would be unsafe.

Also the output of "A: foo B: " when executing the code suggests that. ( https://ideone.com/wKKbdK )

However the much more troublesome thing where I am unsure is expression A: After the std::move I assume I got an xvalue which is both a rvalue and a glvalue, so I am not sure whats the standardized behavior if any, for the type deduction of elementA.

Because from lvalues I almost sure its UB, and lvalues are glvalues, and xvalues are part of them, then the type would of elementA would be std::string&&, which would be unsafe right? (unless the exception for const&& AFAIK)

So to summarize: Is the usage of elementA safe standardized behaviour and what will be its type?

Aucun commentaire:

Enregistrer un commentaire