C++ 包装CString(const char*)以便能够将它们存储到STL容器中

C++ 包装CString(const char*)以便能够将它们存储到STL容器中,c++,boost,stl,typetraits,C++,Boost,Stl,Typetraits,我需要将一些不同类型的变量存储到stl容器中(本例中为std::map)。虽然,当这个变量是字符串时,我不能使用std::string,因为内存使用非常关键 因此,我需要找到一种方法将所有字符串作为cstring(constchar*)存储到该映射中。因此,我尝试编写代码,创建某种类来保存值: template<class T> class ValueHolder { private: T value; public: ValueHolder(const T &

我需要将一些不同类型的变量存储到stl容器中(本例中为std::map)。虽然,当这个变量是字符串时,我不能使用std::string,因为内存使用非常关键

因此,我需要找到一种方法将所有字符串作为cstring(constchar*)存储到该映射中。因此,我尝试编写代码,创建某种类来保存值:

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);
    }
};
模板
类别价值持有人{
私人:
T值;
公众:
估价师(常数T和参数值):
值(argValue){
}
常量T&getValue(){
返回值;
}
~ValueHolder(){}
};
模板
类别价值持有人{
私人:
字符*值;
公众:
值持有人(常量字符*argValue){
值=标准值(argValue);

std::cout还有ideone:…实际上前面的这个线程有一大堆是的,但它不能与boost一起工作。Edit:codepad确实可以!我随时都会添加那个测试程序!谢谢!为什么std::string
比char*更糟糕?
std::string
应该分配与您分配的内存量相同的内存用
char*
吃饭,但要用一个对象包裹它。内存消耗应该是相同的,或者非常相似。在我看来,你似乎花了很多精力来解决一个非问题。你“负担不起”std::string是什么意思?你认为它做什么这么昂贵?[编辑:已经阅读了您对Syffys.OMG的评论。什么?您需要找到一种不同的存储机制,因为25GB的字符串映射(wtf是Go?)不适合使用。解决方案不是让内存管理变成地狱,而是修复不合适的数据模型。]好的,那么你想要固定大小的字符数组,大小等于两个指针。而不是功能齐全的任意大小的动态分配字符串。这是你在任何情况下测量的。你应该从这开始。如果是这样,你不想存储
常量char*
。你根本不想弄脏指针。做一个
struct mystring{char[16]value;}
并完成它。将
struct mystring
(不是指针)存储在地图中。如果您认为需要非
char[16]
的特性,请首先测量非
char[16]
的性能。
std::map<ValueType::Type, boost::any> extensions_;
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;
    }
}