-2

In the funtions bellow, doA is overrided to accept const& and && of std::string, doA_ is overrided to accept these two types of std::initializer_list. But what seems to be wrong is that, in the fisrt doA_ function, a std::move does not correctly cast 'std::string' to 'std::string&&', so there the second doA called,not the first one. Even if I use 'doA(static_case(*it))' instead,it is the same result.However , if I use 'doA("a string")',then the first doA called. Why is that?Why do they behave differently?

#include <string>
#include <iostream>

void doA(std::string &&s)
{
        std::cout << "doA && "<<std::endl;
}

void doA(const std::string &s)
{
        std::cout << "doA const & "<<std::endl;
}
void doA_(initializer_list<std::string> &&l)
{
        std::cout << "doA_ &&"<<std::endl;
        auto it=std::begin(l);
        doA(std::move(*it));//print 'doA const &',but it is expected to be 'doA &&'
        //doA(static_cast<const std::string &&>(*it));  //same with above
        //doA("a string");   //print 'doA &&'
              //======Doesn't work as expected

}
void doA_(const initializer_list<std::string> &l)
{
        std::cout << "doA_ const &"<<std::endl;
        auto it=std::begin(l);
        doA(*it);
}


int main()
{
        initializer_list<std::string> l={"a","b"};
        doA_(l);//doA_ const &
        doA_(std::move(l));//doA_ &&
        doA_({"c","d"});//doA_ &&
        return 0;
}

//=========output
    doA_ const &
    doA const &
    doA_ &&
    doA const &
    doA_ &&
    doA const &
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 3
    Can you please elaborate on the "does not work"? *How* doesn't it work? Do you get build errors? Crashes when running? Unexpected results? Please edit your question to include all those details in the body of the question. Also please take some time to [read about how to ask good questions](http://stackoverflow.com/help/how-to-ask). – Some programmer dude Mar 31 '17 at 15:26

1 Answers1

1

*std::begin(l) is an lvalue of type const std::string, not of type std::string. So std::move(*std::begin(l)) is an rvalue of type const std::string. So doA(std::string&&) cannot be called - binding its parameter would discard the const. Only doA(const std::string&) is a viable function.

aschepler
  • 70,891
  • 9
  • 107
  • 161
  • Hmm, right.So what if I want to really 'move' string from initializer_list to my container? Is there any way that makes elments in initializer_list non-const? – Douglas Fulton Shaw Apr 01 '17 at 02:42