c++中多种数据类型的通用容器
Generic container for multiple data types in C++
使用c++,我试图创建一个通用的容器类来处理多种数据类型。这是一个常见的问题,有各种各样的解决方案,但我没有发现任何…像我在Python甚至VB/VBA等语言中习惯的那样直观…
这是我的场景:
我已经基于boost::any构建了一个DataContainer类,我用它来存储多个元素的多个数据类型。我使用的映射声明为:
std::map<std::string, DataContainer* (or DataContainerBase*)>
,其中DataContainer是封装类型为
的对象的类:std::list<boost::any>
以及管理/访问列表的方便功能。
但是,最后,我仍然被迫在数据容器之外进行类型转换。
例如,如果要在map中存储一个int值列表,访问它们需要:
int value = boost::any_cast<int>(map["myValue"]->get());
我宁愿boost代码完全包含在数据容器结构中,所以我只需要类型:
int value = map["myValue"]->get();
,或者最糟糕的:
int value = map["myValue"]->get<int>();
当然,我可以列举我的数据类型并做如下操作:
int value = map["myValue"]->get( TYPE_INT );
或编写特定类型的get()函数:
getInt(), getString(), getBool() ...
后两个选项的问题是它们有些不灵活,要求我显式声明希望存储在容器中的每种类型。any_cast解决方案(我已经实现并工作)我认为是好的,它只是…不雅的吗?我不晓得。看来我不需要在外部也使用内部机制。
在我看来,在对DataContainer成员函数的调用中传递值而不声明值类型将需要void*解决方案(这是不希望的,原因很明显),并且使用"get()"调用将需要(据我所知)在基类级别定义的"虚拟模板"成员函数,这当然是不允许的。
事实上,我有一个可行的解决方案,实际上,我在这种情况下的使用范围是有限的,大多数解决方案都可以很好地工作。但我想知道是否可能有一个更灵活的方式来管理一个通用的,多类型的数据容器比这。
如果你想为这个添加一些糖:
int value = boost::any_cast<int>(map["myValue"]->get());
,那么你可能想让get()
函数返回一个代理对象,像这样定义+-:
struct Proxy {
boost::any& value;
Proxy(boost::any& value) : value(value) {}
template<typename T>
operator T() {
return boost::any_cast<T>(value);
}
};
那么这个语法就可以了:
int value = map["myValue"]->get();
// returns a proxy which gets converted by any_cast<int>
然而,我建议保持显式,只使用语法:
int value = map["myValue"]->get<int>();
这里get
没有返回一个带有模板方法的代理对象,但它本身是一个模板方法(但与上面显示的模板转换操作符相同)。
今天我已经为您做了一些源代码。我知道这个问题太老了,但也许这一小段代码对某人有帮助。它主要基于boost:any.
/*
* AnyValueMap.hpp
*
* Created on: Jun 3, 2013
* Author: alvaro
*/
#ifndef ANYVALUEMAP_HPP_
#define ANYVALUEMAP_HPP_
#include <map>
#include <boost/any.hpp>
using namespace std;
template <class T>
class AnyValueMap {
public:
AnyValueMap(){}
virtual ~AnyValueMap(){}
private:
map<T, boost::any> container_;
typedef typename map<T, boost::any>::iterator map_iterator;
typedef typename map<T, boost::any>::const_iterator map_const_iterator;
public:
bool containsKey(const T key) const
{
return container_.find(key) != container_.end();
}
bool remove(const T key)
{
map_iterator it = container_.find(key);
if(it != container_.end())
{
container_.erase(it);
return true;
}
return false;
}
template <class V>
V getValue(const T key, const V defaultValue) const
{
map_const_iterator it = container_.find(key);
if(it != container_.end())
{
return boost::any_cast<V>(it->second);
}
return defaultValue;
}
template <class V>
V getValue(const T key) const
{
return boost::any_cast<V>(container_.at(key));
}
template <class V>
void setValue(const T key, const V value)
{
container_[key] = value;
}
};
#endif /* ANYVALUEMAP_HPP_ */
一个简单的用法示例:
AnyValueMap<unsigned long> myMap;
myMap.setValue<double>(365, 1254.33);
myMap.setValue<int>(366, 55);
double storedDoubleValue = myMap.getValue<double>(365);
int storedIntValue = myMap.getValue<int>(366);
- 防止主数据类型C++的隐式转换
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在C++中打印指向不同基元数据类型的指针的内存地址
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 如何计算数据类型的范围,例如int
- C++中数据类型修饰符的顺序
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- 特定数据类型的模板类
- 具有多个模板的模板函数,用于特定数据类型(如字符串)?
- 有没有办法提示用户使用哪种数据类型作为模板 c++
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 时间复杂度 当具有复合数据类型(如元组或对)时?
- 如何获取C++字符数据类型的地址
- 将复杂的非基元C++数据类型转换为 Erlang/Elixir 格式,以使用 NIF 导出方法
- 构造智能点数据类型以及普通数据类型的通用方法
- 如何使映射键具有两种不同的数据类型?
- 数据类型"struct seq<0, 1, 2>{}"含义是什么?
- 如何在不破坏现有应用程序的情况下更改 API 中 stl 容器的数据类型?
- Static_cast转换为错误的数据类型,但结果仍然正确?
- 使用 Boost.Spirit 解析具有混合数据类型的 OBJ 文件?