Move from std::initializer_list

closed account (iL1RX9L8)
Hello!

I'd like to ask you something I've been looking for without luck: moving from std::initializer_lists. It's not possible with the current revision of the standard, but, is it planned in the future? I think it would be something very useful.

Let's take some code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <initializer_list>
#include <vector>
#include <string>
#include <iostream>

class Example
{
    private:
        std::vector<std::string>
            L;
    public:
        explicit
            Example
            ( const std::initializer_list<std::string> & l )
            : L(l)
            {
                return;
            };
        
        void
            print
            ( void )
            {
                for ( const auto & v : L )
                    std::cout << v << std::endl;
                return;
            };
};

int
main
    ( void )
{
    Example example{ "C++" , "mhgc" , "Warcraft" };
    
    return 0;
}


If I have not taken it wrong, three strings would be created to fill the first and only argument of the constructor of Example. As the constructor accepts a const reference, the std::initializer_list object wouldn't be copied, so nothing would happen to the strings. Fast and clear.

But then, when I initialize the vector, each string must be copied, as std::initializer_lists do not allow moving from them. I think this is a bit annoying: what if they weren't simple strings? I usually think of temporaries whenever I see "std::initializer_list"; why don't they help using move semantics?

So, are there any plans to fix this, any workarounds? I would prefer something easy and "elegant". That's why I chose std::initializer_lists: they seemed wonderful.

Thanks! Best regards,
Kalrish
closed account (Dy7SLyTq)
quick question with your code... wouldnt it be
Example example({ "C++" , "mhgc" , "Warcraft" });
because your calling a constructor? and i dont think that works, because L needs to push back the values doesnt it? i dont know initializer lists that well, but i dont think you can throw multiple values at a vector like you can an array
closed account (iL1RX9L8)
The syntax is ok, and the code compiles. I don't know how that feature is called, but I remember I read about it. If you added example.print(); after the line you mentioned, you would see what you expect to be printed (i.e.: "C++\nmhgc\nWarcraft").

L can be constructed that way. The only problem is that it'd copy the elements of the initializer_list. Those elements are objects by themselves inside the initializer_list, but, outside it, they're temporaries. So it would make sense moving from them. (That's what I'm looking for.)
closed account (Dy7SLyTq)
well why not make it initializer_list<string*>? that would move them i believe
an std::initializer_list object is just a pair of pointers or a pointer and a size (which by the way means there's little point in taking it by reference in your constructor - std::vector's constructor takes it by value), which refers to an array, which might be a static const array, at compiler's discretion.

That's why it only provides const access to its members, which prevents (non-contrived) moves from them. It's not what it's for, so there aren't plans to "fix" it. If someone can formulate a proposal or implement in a compiler what you're thinking of, it will likely happen - you're not the first to point out that it is desirable.
Last edited on
Topic archived. No new replies allowed.