2014-02-16 8 views
0

字典以下面的“类型”词典 - 其键应该是类型和数值,其类型的实例:与编译时密钥,或类型作为键

class TypeDictionary { 
public: 
    template<class T> void insert(T t); 
    template<class T> T& get(); 
    // implementation be here -- and the question is about this 
}; 

struct Foo; 
struct Bar; 

void userOfTypeDictionary() { 

    TypeDictionary td; 

    td.insert(Foo()); 
    td.insert(Bar()); 
    td.insert(double(3.14)); 
    // and other unknown (to TypeDictionary) 
    // list of types attached 


    // later on, in a different scope perhaps 
    Foo& f = td.get<Foo>() ; 
    Bar& f = td.get<Bar>(); 
    double pi = tg.get<double>(); 
    // ... 
} 

此特定TypeDictionary具有越来越多的类型被“注册”,但是当然,该设施应该允许任意类型的集合,并且可能为这个类的每个实例设置不同的集合。

至于一个现实的激励用例,请考虑插件管理器。在其任何特定时间,都会附加一组任意的异构对象,而管理者的工作是管理附加对象的生命周期,并在以类型安全的方式查询时返回(引用)给它们。

关于这种事情是否可能的任何想法?如果一个策略涉及使用一个库,比如Boost.Fusion或类似的,那就好了。

回答

2

这样做的最小但可能不是最理想的方式是使用仅在C++ 14中可用的类型版本的std::get。这样,你的字典里只会得到或换一个元组:以上

template<typename... T> 
struct dict 
{ 
    std::tuple<T...> t; 

    template<typename E> 
    void insert(E e) { std::get<E>(t) = e; } 

    template<typename E> 
    E& get() { return std::get<E>(t); } 
}; 

struct Foo {}; 
struct Bar {}; 

using TypeDictionary = dict<Foo, Bar, double>; 

给出期望的行为与clang -std=c++1y但失败g++高达4.8.2至少。

无论如何,这个想法是,你有一个预先给定的类型键的预定义列表,你的字典像一个固定大小的平面集合,这意味着它包括其元素的大小(至少是非空的即使你不打电话insert(),在这种情况下,这些元素是默认构造的。

我在这里没有特别注意给const或非const版本的方法或移动操作。以上只是为了得到这个想法。当然,这很简单,您可以直接使用std::tuplestd::get()

要使字典具有固定类型而不管其元素类型是相当困难的;这是一个类型擦除的问题,在这方面它类似于std::function。为了得到一个真正动态的类型安全的异构容器(没有强制类型,虚函数等),我认为这是不可能的。可能的是在每个insert()操作后获得新的(扩大的)类型的新词典,例如,

auto new_d = d.insert(3.14); 

这会简单地用新的元素串连现有tuple<T...>赋予了新的tuple<T...,double>

+0

感谢您的回答!因此,当你形象化第一个元组版本并没有解决最重要的规范,那就是类型列表没有预定义(如果是的话,Boost.Fusion可以很好地使用,特别是boost ::融合::设置)。下半部分的评论更有意思,实际上,每次插入都有一个不同的基础类型。但是,如果TypeDisctionary以某种方式管理它,通过某种类型的擦除或其他方式,它会更有趣。 – Nick

+0

您可以使用[boost :: any]之类的东西(http://www.boost.org/doc/libs/1_55_0/ doc/html/any.html),尽管它包含令人讨厌的低级代码,如果我没有记错的话,它使用免费商店(我做了一个类似的库,至少不使用免费商店) 。这使得异构容器成为可能,但它本身并不能解决在不同类型中搜索给定密钥的问题。 – iavr

相关问题