【问题标题】:c++ map that contains any type of data, including vectors, maps etc; NO BOOSTc++ map 包含任何类型的数据,包括向量、地图等;没有提升
【发布时间】:2013-11-12 21:49:46
【问题描述】:

我需要一个支持从任何类型到任何类型的映射的地图。

正如标题所说,任何类型都意味着(除其他外)矢量、地图、所有类型的数字等。

我考虑编写某种包装器,正如我在此处 (http://www.parashift.com/c++-faq-lite/heterogeneous-list.html) 发现的那样,映射需要包含异构类型(实际上数组需要,但映射是关联数组)。

对此有什么想法,或者我的方法应该是什么?

谢谢

【问题讨论】:

  • 你可以有一个类型为 enum 的结构体和一个 void* 数据条目
  • 我假设顺序不是一个因素,因为完全不相交的类型,没有。我对您的方法的想法很简单:如果您认为这是一个解决方案,那么您最好确保您了解问题所在,我并不是说您的解决方案存在问题。
  • 复制Boost.Any的相关部分。或使用QVariant
  • 你的意思是需要在同一个map中存储不同的类型?为此,您需要Boost.Any 之类的东西;要么改变你的“NO BOOST”要求,要么自己重写。

标签: c++ map


【解决方案1】:

如果您不能使用 boost,您可以编写自己的“变体”类型。

这将包含:

  • 某个值(字符串或数字)显示它所持有的类型。
  • 存储数据的地方。这可以是联合,也可以是通用数据块,然后由与您的类型关联的解释器进行解释。

鉴于您希望能够将其用于地图的键和值,您必须在变体类型上定义 operator<,或在地图上使用其他一些严格的排序谓词.

请注意,您的地图将能够包含您喜欢的任何类型,只要您为您的类型提供一个键,以及该类型与地图实际存储的不透明数据结构之间的转换器。您还需要在某种表格上注册您的类型。

使用boost::variant,您可以使用的所有类型都是“已注册”的。使用boost::any,类型未注册,但在提取时,您需要知道您希望找到的类型。这些都不能用在映射的键中,但它们可以用在值中。

boost-any 模型不使用任何类型的变量来表示类型。相反,您有一个类似这样的模型(可能更好地实现)

class AbstractBase
{
public:
  virtual ~AbstractBase() {}
};

template< typename T >
struct AnyImpl : public AbstractBase
{
   T t;
};

typedef shared_ptr< AbstractBase > AbstractBasePtr;

class Any
{
   AbstractBasePtr ptr;

 public:
   bool cast( T & t ) const
   {
      shared_ptr<AnyImpl<T>> tptr = pointer_cast< AnyImpl<T> >( ptr );
      if( tptr )
      {
         t = tptr->t;
         return true;
      }
      else
         return false;
   }
};

好的,所以我创建了一个基类,您可以从中派生任何类型的持有者,然后您可以存储指向它的共享指针,因为它们是异构的,然后您可以尝试将它们转换为您想要的类型。

也许是一个有用的学习练习。实际上,与 boost 相比,可能实施得不好。

“派生”的持有者不持有“基”类型,如果您想要指针,您现在将指针包装在不太好的指针中。您的类型必须是可复制和可分配的。但是它可能会起作用。

【讨论】:

  • 正如我在上面的评论中所说,我夸大了“从任意键”,但“到任意值”部分仍然有效。谢谢你的回答,我现在正在考虑这个
  • 对于“任何值”,您不再需要为您的变体类型实现 operator
  • 真的和我当时想的差不多。我会对此进行测试并告诉你它是如何工作的。
【解决方案2】:

"mappings from any type to any type" 的一种方法是针对 std::map 的要求实现any types 的专业化。例如比较键或复制构造函数的值,例如:

temaplate <typename T>
class MapKey {  };

temaplate <typename T>
class MapValue {  };

并像这样定义您的地图:

template <typename TKey, typename TValue>
class Map : public std::map< MapKey<TKey>, MapValue<TValue> > 
{ /* map methods */ };

要将std::vector&lt;int&gt; 用作Map 中的键,您需要实现专门化MapKey&lt;std::vector&lt;int&gt;&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-26
    • 1970-01-01
    • 2013-11-04
    • 2011-07-30
    • 1970-01-01
    相关资源
    最近更新 更多