さまざまな種類の変数を stl コンテナー (この場合は std::map) に格納する必要があります。ただし、この変数が文字列である場合、メモリ使用量が重要であるため、 std::string を使用する余裕はありません。
したがって、すべての文字列を cstring (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 を使用してメモリ使用量を測定するために使用したプログラム:
単純にデーモンにして、top を使用してプロセスのメモリ使用量を調べました。
EDIT3:同じ結果を示す興味深い記事があります: http://jovislab.com/blog/?p=76