2016-11-18 88 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