我需要将一些不同类型的变量存储到 stl 容器中(在本例中为 std::map)。虽然,当这个变量是一个字符串时,我不能使用 std::string 因为内存使用很关键。
因此,我需要找到一种方法将我的所有字符串作为 cstrings (const char*) 存储到该映射中。所以我尝试编写某种类来保存该值:
template<class T>
class ValueHolder {
private:
T value;
public:
ValueHolder(const T &argValue) :
value(argValue) {
}
const T& getValue() {
return value;
}
~ValueHolder() {}
};
template<>
class ValueHolder<const char*> {
private:
char* value;
public:
ValueHolder(const char* argValue) {
value = strdup(argValue);
std::cout << "constructing ValueHolder(const char*) " << value << std::endl;
}
ValueHolder(const ValueHolder<const char*> &argExtension) {
value = strdup(argExtension.value);
}
const char* getValue() const {
std::cout << "returning ValueHolder(const char*) " << value << std::endl;
return value;
}
~ValueHolder() {
if(value != NULL)
free(value);
}
};
然后,我声明了 std::map
std::map<ValueType::Type, boost::any> extensions_;
以下是允许设置和检索它的函数(使用 boost::any):
template<class Type>
Type getExtension(const ValueType::Type &argValueType) const {
std::map<ValueType::Type, boost::any>::const_iterator it = extensions_.find(argValueType);
if(it != extensions_.end()) {
switch(argValueType) {
case ValueType::VAL_INT:
if(boost::is_same<EnumFooType::Type, Type>::value) {
return (boost::any_cast<ValueHolder<Type> >((*it).second)).getValue();
} else {
std::cout << "Wrong type for this value" << std::endl;
}
break;
case ValueType::VAL_STR_1:
case ValueType::VAL_STR_2:
if(boost::is_same<const char *, typename boost::decay<Type>::type>::value) {
return (boost::any_cast<ValueHolder<Type> >((*it).second)).getValue();
} else {
std::cout << "Wrong type value for this Holder" << std::endl;
}
break;
default:
std::cout << "Unhandled type of value, skipping..." << std::endl;
break;
}
}
throw ValueNotFoundException("Could not find a value for this subscriber extension");
}
template<class T>
void setExtension(const ValueType::Type &argExtensionType , T argExtensionValue) {
boost::any any_value;
switch(argExtensionType) {
case ValueType::VAL_INT:
if(boost::is_same<EnumFooType::Type, T>::value) {
any_value = ValueHolder<T>(argExtensionValue);
extensions_[argExtensionType] = any_value;
} else {
std::cout << "Wrong type value for Billing subscriber extension" << std::endl;
}
break;
case ValueType::VAL_STR_1:
case ValueType::VAL_STR_2:
if(boost::is_same<const char *, typename boost::decay<T>::type>::value) {
any_value = ValueHolder<T>(argExtensionValue);
extensions_[argExtensionType] = any_value;
} else {
std::cout << "Wrong type for this value, it should be a cstring!" << std::endl;
}
break;
default:
std::cout << "Unhandled value type, skipping..." << std::endl;
break;
}
}
问题是指定类型为cstring(const char*)时返回的值不对,这是我的测试程序输出:
构造 ValueHolder(const char*) FR
良好的枚举值:)
返回 ValueHolder(const char*) FR
!!!错误!!!值为 �� 而不是 FR
如果需要,我稍后会提供在线测试程序,但 liveworkspace 和 coliru 目前都已关闭。
任何帮助表示赞赏,在此先感谢!
编辑:这是一个测试程序:http ://codepad.org/zbLQDAiS
EDIT2:这里我用 const char* 和 std::string 测量内存使用情况的程序:http ://coliru.stacked-crooked.com/view?id=3b3c4d7ce1d8d1400e3f6e45f75040dc-9294698a18feab30c803b17d837ba467
我只是把它做成了一个守护进程,并使用 top 查看了进程的内存使用情况。
EDIT3:这是一篇有趣的文章,显示了相同的结果:http: //jovislab.com/blog/ ?p=76