C++用于类模板的初始化程序列表构造函数

问题描述:

我有一个带模板参数T的类模板Templ,并且Templ类有一个名为obj的T类数据成员。我写的参数转发到OBJ构造器的可变参数的构造函数模板:C++用于类模板的初始化程序列表构造函数

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

现在我意识到,类型T可以是与初始化列表构造函数的类,我希望它是通过TEMPL访问。所以我查了一下std::list::emplacestd::make_shared是做什么的。他们有像我这样的可变参数函数,但是他们没有覆盖init-list。因为某些原因。

所以第一个问题:为什么?我的意思是,如果我用init-list ctor使用某个类T,然后使用std::list<T>?为什么list :: emplace没有一个带有initializer_list的版本?也许有一个很好的理由我应该这样做......所以我想知道。

另外,无论STL做什么 - 我应该提供一个init-list ctor作为优秀的设计吗?我的意思是,它就像变种ctor一样,对吧?允许用户选择任何类型或类别T用于Templ <>,并直接调用为T定义的任何ctor。即使它是一个采用初始列表的ctor。

+0

你的第一个问题是一个很好的问题,但其他三个问题应该是单独的帖子。 – 2013-02-11 02:32:54

+0

@VaughnCato我把他们中的一个分开了。我可以在20分钟后发布一次,所以我无法修复其余的...直到下一次 – cfa45ca55111016ee9269f0a52e771 2013-02-11 03:12:49

+0

完成,现在只有1个问题 – cfa45ca55111016ee9269f0a52e771 2013-02-11 10:52:47

与转发initializer_list构造的问题是,除了最微不足道的参数类型不抵扣(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' 

因为你必须写在大多数情况下m{std::initializer_list<...>{...}},没有多少点只为原始提供它,当然不是为了这个标准。

如果您认为任何有趣的initializer_list参数可能适用于容器类型,您可以查看Optionally supporting initializer_list construction for templates maybe wrapping containers中采用的方法。

+0

我不希望打包容器,但我确实想要支持一个具有init - 清单ctor。在哪些情况下扣除不起作用?如果用作模板参数的类有一个ctor采用基元类型变量的初始列表,或者我定义的类的对象的初始列表(不是一对或一个容器或类似的东西),它是否可以工作?另外,我是否必须使用enable_if?如果我不这样怎么办? – cfa45ca55111016ee9269f0a52e771 2013-02-11 13:28:34

+1

@ fr33domlover如果你的初始化器的形式为{x1,x2,...},其中所有的'x'都是相同类型的prvalue表达式,那么你很好;问题是如果你有嵌套大括号。如果你想使用统一初始化,'enable_if'是必须的。 'initializer_list'构造函数是贪婪的(13.3.1.7)。 – ecatmur 2013-02-11 13:41:09

+1

我们当然需要下一个C++的initializer_tuple内在类型,它允许支持初始化器列表的完美转发,无论它们是同构的还是异构的。 – 2013-02-11 19:17:15