我有一个类myclass,它有一个私有成员param_map
class some_class {
private:
std::map<std::string,std::shared_ptr<parameter> > param_map;
};
我想公开这个地图以允许其他类,我已经创建了add,delete,get参数方法,这些都是你想的。但是我想公开这个,以便其他类可以遍历地图。
Q1:最安全的方法是什么。
参数也有一个成员值,我想成为int / float / bool,所以一个选项是使用模板定义它
template<class T>
class parameter {
public:
T get_value { return value_; }
private:
T value_;
}
Q2:但是我如何将这种类型存储在地图中?它将如何改变param_map的定义。另外我会考虑非模板解决方案(但我更喜欢只有一张地图)
PS:我宁愿避免使用boost,我更喜欢使用c ++ x0 std lib,但如果boost是最佳选择,那么我会考虑这一点。如果你也可以发布代码示例,那将是件好事。此致
标记
答案 0 :(得分:1)
Q1:您可以公开迭代地图的迭代器,就像std :: map一样。
Q2:您可以使用3个不同的地图,或使用boost :: any来存储该值。如果你想避免提升,你可以存储void *代替boost :: any(但我通常不会采用void *方式 - 我宁愿使用所需的boost部分)。
答案 1 :(得分:1)
Q1:你可以提供一个foreach()成员函数,它接受一个仿函数作为参数。 foreach函数将遍历地图并在地图中的每个项目上调用仿函数。然后调用者可以使用C ++ 0x lambda函数来创建仿函数。
#include <string>
#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
class container {
public:
container() {
_m["one"] = 1;
_m["two"] = 2;
_m["three"] = 3;
}
template <class FN>
void foreach(FN func) {
std::for_each(_m.begin(), _m.end(), func);
}
private:
map<string, int> _m;
};
void main(int, char** a)
{
container c;
c.foreach([](pair<string,int> p) -> void {
cout << p.first << ", " << p.second << endl;
});
}
我没有方便的C ++ 0x兼容编译器,因此可能需要进行一些调整才能编译。
Q2:我知道你不想使用提升,但我认为boost.variant可能是你最好的选择。你可以使用一个有区别的联盟,但我会非常犹豫地放弃类型安全性boost.variant给你。
enum type { int_t, float_t, bool_t };
struct item {
type t;
union {
int i;
float f;
bool b;
};
};
答案 2 :(得分:0)
我会使用boost::any
作为模板类型。你可以自己重新实现(作为一项很好的练习),但这会浪费你的时间。
至于Q1,为什么不简单地将地图公之于众?你最终会为map中的大多数方法提供加入函数,比如operator [],iterators等。所以公开它并不是一个坏主意:
struct MyClass
{
map<string, any> parameters;
// For convenience
template <typename T>
T const& getParameter(string const& s) const
{
map<string, any>::const_iterator i = parameters.find(s);
if (i == parameters.end()) throw /* something */;
return any_cast<T const&>(*i);
}
template <typename T>
T& getParameter(string const& s)
{
map<string, any>::iterator i = parameters.find(s);
if (i == parameters.end()) throw /* something */;
return any_cast<T&>(*i);
}
};
MyClass x;
x.parameters["foo"] = 2.5;
x.parameters["bar"] = string("Hey");
double xfoo = x.getParameter<double>("foo");
string const& xbar = x.getParameter<string>("bar");
for_each(x.parameters.begin(), x.parameters.end(), baz);