2016-11-06 39 views
1

我有一个很难合成我的问题得到,我不知道标题总结得很好:/应用到包含的对象的功能,只要从基本型

我想保持一个结构中的多态容器的映射,以便有一个漂亮的平面对象数组。

我的麻烦是我想对包含的对象应用一个函数,但只有那些从指定的Base类型派生的函数。下面有一个我试图实现的简化版本。

struct BaseStock {}; 

template <typename ContainedType> 
struct Stock : BaseStock { 
    std::vector<ContainedType> container; 
}; 

struct Store { 
    std::unordered_map<std::type_index, std::unique_ptr<BaseStock>> stocks; 

    template <typename Base> 
    void something() { 
     for (auto& pair: stocks) { 
      // Here, do somehting only if pair.second's 
      // contained type derives from Base 
     } 
    } 
}; 

我试图访问包含从BaseStock元素通过返回void*但它不可能dynamic_cast从它,从而不允许类型检查。 stocks地图保留了股票所包含类型的type_index,但是无法从中获取层次结构信息。

允许BaseStock返回的东西,可以对被检查似乎是最接近的解决方案,但它意味着迫使ContainedType总是从某事物(这是不坏,但我喜欢的想法容器,不会对您使用的类型施加限制)

非常感谢您的帮助!

回答

1

我认为这是做你想做的事情,随时要求对你在评论中没有得到的东西作更大的解释。

#include <vector> 
#include <iostream> 
#include <unordered_map> 
#include <typeindex> 
#include <memory> 

struct BaseStock {}; 
template <typename ContainedType> 
struct Stock : BaseStock { 
    std::vector<ContainedType> container; 
}; 

struct Store { 
    std::unordered_map<std::type_index, std::unique_ptr<BaseStock>> stocks; 
    template <typename Base> 
    void something() { 
     for (auto& pair: stocks) { 
      if (typeid(pair.first) != typeid(Base)) { 
       std::cout << "Checking via typeid.\n"; 
      } 
     } 
    } 
}; 

template<typename BaseType, typename DerivedType = BaseType> 
void InsertIntoStore(Store* store) { 
    store->stocks[typeid(BaseType)] = 
     std::unique_ptr<BaseType>(std::make_unique<DerivedType>()); 
} 

int main() { 
    Store store; 
    // Put two things into the map. 
    InsertIntoStore<BaseStock, Stock<int>>(&store); 
    InsertIntoStore<BaseStock>(&store);  
    // But only get one output. 
    store.something<BaseStock>(); 
} 
+0

在您的实现中,每个type_index仍然只能有一个BaseStock!放置一个BaseStock矢量解决了这个问题。 但是你的回答无论如何都是正确和有趣的:) – brainsandwich

+0

你想要一个'unordered_multimap',你没有在你的问题中避开它。如果能够充分回答您发布的问题,请接受我的回答。 – druckermanly

+0

是啊,我还在等待其他方面的其他答案,但你的确“充分回答了”我发布的问题 – brainsandwich