One possible way to avoid ambiguity is to use static factory methods as a means of isolating the initializer_list constructor from others.
For instance:
template <typename T> class Container { public: static Container with(size_t count, const T& value) { return Container(Tag{}, count, value); } Container(std::initializer_list<T> list) {} private: struct Tag{}; Container(Tag, size_t count, const T& value) {} };
Using:
auto c1 = Container<int>::with(1, 2);
This static factory approach recalls how objects are allocated and initialized in Objective-C . The nested Tag structure is used to ensure that the initializer_list overload is not viable.
Alternatively, the initializer_list constructor can be changed to a static factory method, which allows you to save other constructor problems:
template <typename T> class Container { public: static Container with(std::initializer_list<T> list) { return Container(Tag{}, list); } Container(size_t count, const T& value) {} private: struct Tag{}; Container(Tag, std::initializer_list<T> list) {} };
Using:
auto c1 = Container<int>{1, 2};
source share