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 ...) {} }; 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!).
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) ...} {} };