How to redirect std :: initializer_list <T>?

I am trying to forward std::initializer_list but

 no known conversion from 'std::initializer_list<A>' to 'std::initializer_list<B>' 

Here is the test code

 #include <iostream> class B { }; class A: public B { }; class not_working { private: void fun(std::initializer_list<B> p) { } public: template<typename T> not_working(std::initializer_list<T> args) { fun(args); } }; class working { private: void fun(std::initializer_list<B> p) { } public: working(std::initializer_list<B> args) { fun(args); } }; int main(){ working{A{}, A{}}; //not_working{A{}, A{}}; } 

How can I send std::initializer_list
without explicit casting not_working{(B)A{}, (B)A{}}; ?

Why is this problem for me?

I have a proxy class that sends constructor parameters to the class. Something like that:

  template<typename T> class proxy { T real; template<typename S> proxy(std::initializer_list<S> p): real(p) {} template<typename S...> proxy(S ... p): real(p ...) {} }; 
+7
c ++ c ++ 11 initializer-list
source share
2 answers

You cannot, and the reason is the same as why you also could not use std::vector<A> for std::vector<B> . Different types of containers are completely unrelated.

The only way to "change" the type of container is to create a new container of a new type (for example, std::vector<B>(a.begin(), a.end()) - but beware of slicing!).

+3
source share

Sending an answer from the comments of the question to increase the visibility of the solution:

The standard solution is to use std :: forward. This does not allow forwarding initializer lists.

 template<typename T> class proxy { T real; public: template<typename ... S> proxy(S ... p): real{std::forward<S>(args)...} {} }; 

Using std :: move also works with std :: initializer_list (provided by @dyp):

 template<typename T> class proxy { T real; public: template<typename ... S> proxy(S ... p): real{std::move(p) ...} {} }; 
0
source share

All Articles