2013-02-11 60 views
4

我有一個帶模板參數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

回答

2

與轉發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

相關問題