我写了一个C ++模板类,但我没有实例化类的类型。类型以字符串格式存储。所以我必须做这样的事情:
if ( propType == "char") {
Property<char> pChar = ...
} else if ( propType == "int") {
Property<int> pChar = ...
} if ( propType == "double") {
Property<double> pChar = ...
}
我不喜欢这个if-else-
循环,是否有任何方法可以避免这种情况,或者是否有其他解决此问题的方法?
答案 0 :(得分:4)
有许多方法,但如果不知道如何在特定情况下使用它,就不可能选择一个好方法。
作为示范:
Property<T>
类都继承自PropertyBase
以下是一些代码:
using PropertyPtr = std::unique_ptr<PropertyBase>;
using Parser = std::function<PropertyPtr(std::string const&, std::string const&)>;
template <typename T>
PropertyPtr parse(std::string const& type, std::string const& value) {
T v = boost::lexical_cast<T>(value);
return PropertyPtr(new Property<T>(std::move(v)));
}
std::map<std::string, Parser> const parsers = {
std::make_pair("char", parse<char>),
std::make_pair("int", parse<int>),
std::make_pair("double", parse<double>)
};
void dummy(std::string const& type, std::string const& value) {
auto const it = parsers.find(type);
assert(it == parsers.end() && "No parser");
auto const& parser = it->second;
PropertyPtr property = parser(type, value);
// do something with property
}
希望这有帮助。
答案 1 :(得分:1)
这里有几点需要考虑。
假设您要从磁盘解析文件,然后根据要创建对象的磁盘类型。您以一种难以区分的方式处理这些对象。您正在使用的类型列表有限。
我将使用的答案是boost::variant
来存储数据,以及map
(如Matthiew的答案)将类型名称映射到阅读器(或解析器)对于类型。然后读者返回boost::variant<int, double, char, string, etc>
。
代码以伪统一方式与变体交互。辅助函数使用boost函数调用仿函数与variant
进行交互。
typedef boost::variant<int, double> myVariant;
typedef std::function< myVariant( input_stream_type& ) > ValueParser;
ValueParser GetParser( std::string typename );
// ...
struct DoTypeSpecificWork
{
typedef void result_type;
void operator()( int ) { /* ... int code goes here */ }
void operator()( double ) { /* ... double code goes here */ }
};
ValueParser parser = GetParser( propType );
myVariant var = parser( input_stream );
boost::variant::apply_visitor( DoTypeSpecificWork(), var );
另一种选择是拥有一个基类PropertyBase
类,它具有与类型无关的抽象接口。然后是Property<T>
子类,为每种类型实现这些抽象接口。创建这些Property<T>
子类可以直接完成(强制解析器了解您的Property
类),也可以间接创建(即,您获取variant
并生成适当的Property<T>
},它解析为从类型抽象中解析代码。)
基本上,您需要在类型擦除,类型抽象和基于模板的编程之间做出决定来处理多种类型。他们都有自己的优势。