2016-11-18 91 views
6

我有很多的功能非常相似,但與當地對象的不同數量和類型上運行:如何遍歷可變參數模板參數以創建可變數量的局部變量?

template <class T> T* create1(const std::vector<std::string>& names) 
{ 
    A a(names[0]); 
    B b(names[1]); 
    C c(names[2]); 

    if (a.valid() && b.valid() && c.valid()) 
     return new T(a, b, c); 
    else 
     return NULL; 
} 

template <class T> T* create2(const std::vector<std::string>& names) 
{ 
    D d(names[0]); 
    E e(names[1]); 

    if (d.valid() && e.valid()) 
     return new T(d, e); 
    else 
     return NULL; 
} 

create1<ABC>({ "nameA", "nameB", "nameC" }); 
create2<DE>({ "nameD", "nameE" }); 

會可變參數模板幫助我實現這些功能,因爲這一個重構?

template <class T, typename Args...> T* create() 
{ 
    // loop over Args and create 2 or 3 objects 
    // if (....valid()) 
    // return T(...); 
    // else 
    // return NULL; 
} 

create<ABC,A,B,C>({ "nameA", "nameB", "nameC" }); 
create<DE,D,E>({ "nameD", "nameE" }); 

經過How can I iterate over a packed variadic template argument list?iterating over variadic template's type parameters沒有成功。看不到我怎麼能創建一個可變數量的不同類型的本地對象...

+0

他們*需要*是本地對象嗎?或者臨時工好嗎? – Rakete1111

+0

如果可能,我寧願選擇本地,因爲實際上它們的創建可能會失敗,然後導致函數的提前返回。更新了帖子。 – jpo38

+0

爲什麼不檢查向量名稱的大小並執行if語句?你只能用一個函數完成所有這些。這不是可變模板的目的。也許你想使用[cstdarg](http://www.cplusplus.com/reference/cstdarg/)? – Stargateur

回答

10

首先,不要把你的名字當作vector。把它們作爲參數包。而且,而且,把它們當成你真正想要的包:

bool is_valid() { return true; } 
template <class T, class... Ts> 
bool is_valid(T& arg, Ts&... args) { 
    return arg.valid() && is_valid(args...); 
} 

template <class T, class... Args> 
T* create(Args&&... args) { 
    if (is_valid(args...)) { 
     return new T{args...}; 
    } 
    else { 
     return nullptr; 
    } 
} 

現在只要通過正確的事:

create<T>(A{"nameA"}, B{"nameB"}, C{"nameC"}); 
create<T>(D{"nameD"}, E{"nameE"}); 

如果由於某種原因,你真的要分開類型和名稱,你也可以這樣做:

template <class T, class... Cs, class... As> 
T* create_classes(As&&... args) { 
    return create<T>(Cs{std::forward<As>(args)}...); 
} 
+0

其實不,我大概簡化了這個例子。看到編輯後,我需要更靈活的東西。 – jpo38

+0

我被卡住了C++ 11 ... – jpo38

+0

爲什麼你需要兩個參數包到'create_classes'? – krzaq