gpt4 book ai didi

c++ - 成员函数的部分特化

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:54:15 24 4
gpt4 key购买 nike

我在模板特化方面遇到问题。下面是两个类,AbstractSetting(父类)和 Setting(子类)。 (AbstractSetting 可能并不重要,但我将其包含在上下文中。)

这段代码的最终目标是创建一个容器来保存不同类型的各种 INI 设置——字符串、整数、枚举等 (DataType),可以用枚举 (IndexType) 引用。在不同的上下文(主游戏、测试套件、服务器等)中可能有不同的索引枚举。

我正在尝试创建一系列 fromString 方法,当传递一个字符串时,这些方法返回一个 DataType 对象(我的模板参数之一)。

所提供的代码将编译但不会链接。

如果我取消对断言的注释,它会链接,但不会调用任何特化,并且无论参数如何,每次调用 fromString 时都会触发断言。

我怎样才能使这项工作?

请注意,U32、S32 等是整数类型。

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 &section, 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); }

然后,在设置类中,我用这个调用替换了类似的代码块:

DataType fromString(const string &val) { 
return mEvaluator.fromString<DataType>(val);
}

这似乎工作得很好,而且可读性很好。

如果有人感兴趣,完整的代码将在下面的链接中提供,在它经过更全面的测试和 checkin 之后。

https://code.google.com/p/bitfighter/source/browse/zap/Settings.h

关于c++ - 成员函数的部分特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22571530/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com