8

Consider the following code:

class StringTokenizer 
{
private:
    char m_delimiter;
    std::istringstream m_string;

public:
    explicit StringTokenizer(const std::string& str, char delimiter)
    : m_string(str)
    , m_delimiter(delimiter)
    {
    }

    template <class Container>
    operator Container ()
    {
        Container container;
        for (std::string token; std::getline(m_string, token, m_delimiter); )
        {
            container.insert(container.end(), token);
        }
        return container;
    }
};

This is the usage:

vector<string> tmp = StringTokenizer("123 456", ' '); //Please note the implicit conversion

When debugging the following happens (Using VS2013):

At the return statement of conversion operator

  1. new vector constructed from container by moving
  2. container gets destructed

After function return:

  1. tmp is constructed by copy constructor

My question is why isn't tmp constructed by move constructor ?

As I understand things function return type is rvalue and should be moved.

cpplearner
  • 13,776
  • 2
  • 47
  • 72
  • 1
    possible duplicate of [c++11 Return value optimization or move?](http://stackoverflow.com/questions/17473753/c11-return-value-optimization-or-move) – Ami Tavory Jun 23 '15 at 07:54
  • 2
    Hmm g++ and clang++ (libstdc++ and libc++) *do* move the `vector`: http://coliru.stacked-crooked.com/a/27aacf34fc3e22b3 while VS2013 copies it: http://rextester.com/JEXDDD72242 – dyp Jun 23 '15 at 07:59
  • VS2013 also moves the vector when calling the conversion operator explicitly: http://rextester.com/SSMH48781 – dyp Jun 23 '15 at 08:00
  • 1
    VS2015 also moves. Just a bug, I suppose. – T.C. Jun 23 '15 at 08:01
  • @dyp When the conversion is implicit VS2013 copy rather than moving – Alejandro Freeman Jun 23 '15 at 08:15
  • @AlejandroFreeman I know, I just don't understand it. T.C.'s probably right, this looks like a bug. – dyp Jun 23 '15 at 08:32
  • shouldn't this do a NRVO? – sp2danny Jun 23 '15 at 09:45

1 Answers1

2

VS2013 doesn't automatically generate the move constructor/assignment. This is solved in later versions.

https://msdn.microsoft.com/en-us/library/hh567368.aspx#rvref