[英]Partial specialization of member functions
我在模板專業化方面遇到問題。 下面是兩個類,AbstractSetting(父級)和Setting(子級)。 (AbstractSetting可能並不重要,但出於上下文考慮,我將其包括在內。)
此代碼的最終目標是創建一個容器,以容納各種不同類型的INI設置-字符串,整數,枚舉等(數據類型),可以用枚舉(IndexType)進行引用。 在不同的上下文(主游戲,測試套件,服務器等)中可能會有不同的索引枚舉。
我正在嘗試創建一系列fromString方法,這些方法在傳遞字符串時返回DataType對象(我的模板參數之一)。
顯示的代碼將編譯但不會鏈接。
如果我取消注釋斷言,它將鏈接,但不會調用任何專業化,並且斷言將在每次對fromString的每次調用時觸發,而與參數無關。
我該如何進行這項工作?
請注意,U32,S32等是int類型。
template <class IndexType>
class AbstractSetting
{
private:
IndexType mName; // Value we use to look this item up
string mIniKey; // INI key
string mIniSection; // INI section
string mComment;
public:
// Constructor
AbstractSetting(IndexType name, const string &key,
const string §ion, const string &comment):
mIniKey(key),
mIniSection(section),
mComment(comment)
{
mName = name;
}
~AbstractSetting() { /* Do nothing */ } // Destructor
IndexType getName() const { return mName; }
string getKey() const { return mIniKey; }
string getSection() const { return mIniSection; }
string getComment() const { return mComment; }
virtual void setValFromString(const string &value) = 0;
virtual string getValueString() const = 0; // Returns val as str
virtual string getDefaultValueString() const = 0; // Returns def val as str
};
////////////////////////////////////////
////////////////////////////////////////
template <class DataType, class IndexType>
class Setting : public AbstractSetting<IndexType>
{
typedef AbstractSetting Parent;
private:
DataType mDefaultValue;
DataType mValue;
public:
Setting(IndexType name, const DataType &defaultValue, const string &iniKey,
const string &iniSection, const string &comment):
Parent(name, iniKey, iniSection, comment),
mDefaultValue(defaultValue),
mValue(defaultValue)
{
// Do nothing
}
~Setting() { /* Do nothing */ }
// Templated declaration
DataType fromString(const string &val) ; //{ Assert(false, "Specialize me!"); }
// Specializations
template<string *> string
fromString(const string &val) { return val; }
template<S32 *> S32
fromString(const string &val) { return atoi(val.c_str()); }
template<U32 *>
U32 fromString(const string &val) { return atoi(val.c_str()); }
template<U16 *>
U16 fromString(const string &val) { return atoi(val.c_str()); }
template<DisplayMode *>
DisplayMode fromString(const string &val) { return stringToDisplayMode(val); }
template<YesNo *>
YesNo fromString(const string &val) { return stringToYesNo(val); }
template<RelAbs *>
RelAbs fromString(const string &val) { return stringToRelAbs(val); }
template<ColorEntryMode *>
ColorEntryMode fromString(const string &val) { return stringToColorEntryMode(val); }
template<GoalZoneFlashStyle *>
GoalZoneFlashStyle fromString(const string &val) { return stringToGoalZoneFlashStyle(val); }
template<Color *>
Color fromString(const string &val) { return Color::iniValToColor(val); }
void setValue(const DataType &value) { mValue = value; }
DataType getValue() const { return mValue; }
string getValueString() const { return toString(mValue); }
string getDefaultValueString() const { return toString(mDefaultValue); }
void setValFromString(const string &value) { setValue(fromString(value)); }
};
我找到了解決方案!
由於成員函數似乎不能部分地專門化,因此我通過創建一個不使用IndexType參數的新類解決了該問題。
class Evaluator
{
public:
template <class DataType> DataType fromString(const string &val);
};
在.cpp文件中,我添加了:
// Templated default - needs to be overriden
template<class DataType> DataType
Evaluator::fromString(const string &val) {
Assert(false, "Specialize me!");
return DataType();
}
// Specializations.
// NOTE: All template specializations must be declared in the namespace scope to be
// C++ compliant. Shame on Visual Studio!
template<> string
Evaluator::fromString(const string &val) { return val; }
template<> S32
Evaluator::fromString(const string &val) { return atoi(val.c_str()); }
template<> U32
Evaluator::fromString(const string &val) { return atoi(val.c_str()); }
template<> U16
Evaluator::fromString(const string &val) { return atoi(val.c_str()); }
template<> DisplayMode
Evaluator::fromString(const string &val) { return stringToDisplayMode(val); }
template<> YesNo
Evaluator::fromString(const string &val) { return stringToYesNo(val); }
template<> RelAbs
Evaluator::fromString(const string &val) { return stringToRelAbs(val); }
template<> ColorEntryMode
Evaluator::fromString(const string &val) { return stringToColorEntryMode(val); }
template<> GoalZoneFlashStyle
Evaluator::fromString(const string &val) { return stringToGoalZoneFlashStyle(val); }
template<> Color
Evaluator::fromString(const string &val) { return Color::iniValToColor(val); }
然后,在Setting類中,我將此調用替換為類似的代碼塊:
DataType fromString(const string &val) {
return mEvaluator.fromString<DataType>(val);
}
這似乎工作得很好,並且可讀性很強。
如果有興趣的人,可以在下面的鏈接上找到完整的代碼,經過更全面的測試和簽入。
https://code.google.com/p/bitfighter/source/browse/zap/Settings.h
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.