2017-06-01 29 views
0

我想查找给定类型的所有对象并将它们添加到向量中。 现在我有一些代码:如何查找在可变参数模板参数中给出的所有类对象

template<class T> 
void fill1(std::vector<Character*> &vec2) 
{ 
    for (int i = 0; i < GameObject::allObjects.size(); i++) 
    { 
     if (dynamic_cast<T>(GameObject::allObjects[i])) 
     { 
      vec2.push_back(dynamic_cast<Character*>(GameObject::allObjects[i])); 
     } 
    } 
} 

template<class First, class ...T> 
void fill2(std::vector<Character*> &vec2) 
{ 
    fill1<First>(vec2); 
    fill2<T...>(vec2); 
} 

template<class ... T> 
std::vector<Character*> SpecialList<T...>::get() 
{ 
     std::vector<Character*> vec2; 
     fill2<T...>(vec2); 
     return vec2; 
} 

的代码不会编译的。 我们得到的错误是: 不能推导出模板参数为“第一”

我知道,所有给定类型从阶级性继承和我有我的所有对象的矢量(游戏物体:: allObjects)。

+1

轻移你在正确的方向:你期望发生的时候'fill2 ( vec2);当'T'是一个空类型列表时调用''? – cdhowie

+0

问题是我不太明白。我希望如果没有争论就会结束。我不知道如何检查是否有任何问题。 – semidude

+0

那么,如果没有至少一个模板参数:'First',你就不能实例化'fill2()'。 – cdhowie

回答

0

取而代之的是虚拟阵列例如列表初始化内部递归使用参数包扩展:

#include <vector> 
#include <memory> 
#include <tuple> 
#include <iostream> 
#include <algorithm> 

template <class... Ts> 
struct tag { }; 

template <class T> 
struct Predicate { 
    template <class U> 
    bool operator()(std::shared_ptr<U> sp) const { 
     return std::dynamic_pointer_cast<T>(sp) != nullptr; 
    } 
}; 

template <class... Ts, class T> 
std::vector<std::shared_ptr<T>> all(std::vector<std::shared_ptr<T>> &v, tag<Ts...>) { 
    std::vector<std::shared_ptr<T>> result; 
    int dummy[] {(std::copy_if(v.begin(), v.end(), std::back_inserter(result), Predicate<Ts>{}),0)...}; 
    static_cast<void>(dummy); 
    return result; 
} 

struct A { 
    virtual ~A() = default; 
}; 

struct B: A { }; 
struct C: A { }; 

int main() { 
    std::vector<std::shared_ptr<A>> v { std::make_shared<A>(), 
             std::make_shared<A>(), 
             std::make_shared<B>(), 
             std::make_shared<B>(), 
             std::make_shared<C>(), 
             std::make_shared<C>() }; 

    std::cout << all(v, tag<B, C>{}).size() << std::endl; 
} 

[live demo]

+0

请注意,在使用参数扩展时,标准不会规定扩展表达式的评估顺序。 – cdhowie

+0

@cdhowie你正在混合参数扩展与表达式评估顺序...在我的例子中,我展开了参数包在初始化列表内。这在扩展后会看起来或多或少像这样:'int dummy [] = {Ex1,Ex2,...,ExN}; '。这些表达式的评估顺序通过C++标准(从左到右)进行了很好的定义。你可以阅读更多关于它[这里](https://stackoverflow.com/a/14443030/4324224)。你可能虽然关于表达式的评估作为函数参数传递,它们是实现定义的... –

相关问题