C++ Supply initializer-list constructor for class template

匆匆过客 提交于 2019-12-01 04:39:58

问题


I have a class template Templ with template parameter T, and the Templ class has a data member of type T, called obj. I wrote a variadic constructor template which forwards the arguments to obj's constructor:

template <class T>
class Templ
{
public:
     template <class... Args> explicit Templ (Args&&... args)
     : obj (std::forward<Args>(args)...)
     {
     }
private:
     T obj;
};

Now I realized that type T may be a class with an init-list constructor, and I want it to be accessible via Templ. So I checked what std::list::emplace and std::make_shared do. They have a variadic function like mine, but they don't have overrides taking an init-list. For some reason.

So first question: why? I mean, what if I use some class T with an init-list ctor, and then I use std::list<T>? Why does list::emplace not have a version that takes an initializer_list? Maybe there's a good reason I should do it either... so I want to know.

Also, regardless of what the STL does - should I supply an init-list ctor as good design? I mean, it's just like the variadic ctor, right? Allowing the user to choose any type or class T to use with Templ<> and directly call any ctor defined for T. Even if it's a ctor taking an init-list.


回答1:


The problem with forwarding initializer_list constructors is that all but the most trivial argument types aren't deducible (Templates don't always guess initializer list types):

#include <map>
template<typename T> struct U {
   T t;
   template<typename...A> explicit U(A&&...a): t(std::forward<A>(a)...) {}
   template<typename L, typename = typename std::enable_if<
      std::is_constructible<T, std::initializer_list<L>>::value>::type>
      explicit U(std::initializer_list<L> l): t(l) {}
};
U<std::map<int, int>> m{{{0, 1}, {2, 3}}};  // fails, couldn't deduce 'L'

Since you'd have to write m{std::initializer_list<...>{...}} in most cases, there's not much point providing it just for primitives, and certainly not for the standard to do so.

If you think that any interesting initializer_list arguments are likely to be for container types, you could look at the approach taken in Optionally supporting initializer_list construction for templates maybe wrapping containers.



来源:https://stackoverflow.com/questions/14805005/c-supply-initializer-list-constructor-for-class-template

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!