我有以下工厂功能:
std::auto_ptr<IPath> PathFactory(std::string const& branch_type, CPathModel const& path_model)
{
using namespace boost::assign;
using namespace boost::phoenix::placeholders;
typedef boost::function<IPath* (CPathModel const&)> PathFactoryFunction;
typedef boost::unordered_map<std::string, PathFactoryFunction> FactoryMap;
static FactoryMap factory_map = map_list_of<std::string, PathFactoryFunction>
("plu", &phx::new_<CPluPath>)
("time_of_day", &phx::new_<CTimeOfDayPath>)
("probability", &phx::new_<CProbabilityPath>)
;
std::auto_ptr<IPath> new_path;
FactoryMap::const_iterator it = factory_map.find(branch_type);
if (it != factory_map.end())
{
new_path.reset(it->second(path_model));
}
return new_path;
}
此代码无法编译,请注意我使用的是C ++ 03。我在这里要做的是创建一个字符串映射到小函数对象,可以分配一个特定类型的对象。每个对象采用相同类型的单个构造参数(CPathModel const&
)。
phx::new_
有几个重载,所以直接引用它可能不是最好的主意,但我希望每个人都可以帮我找到一种方法来使用boost :: phoenix来清理这段代码并使映射工作优雅。
此时似乎更容易定义一个带有重载()
运算符的小模板类,该运算符接受参数并且只在new T(p1)
内部执行。但这是样板并且看起来很简单,以至于某些地方的提升必须有一个很好的解决方案...
答案 0 :(得分:1)
凤凰是懒惰算子的实用工具。
这里你不需要(看见表达模板)。
因此,您可以制作自己的工厂方法模板:
template <typename PathType> IPath* make_path(CPathModel const& model) {
return new PathType(model);
}
并使用它:
static FactoryMap factory_map = map_list_of<std::string, PathFactoryFunction>
("plu", &make_path<CPluPath>)
("time_of_day", &make_path<CTimeOfDayPath>)
("probability", &make_path<CProbabilityPath>)
;
完成工作。
虽然在这一点上,使用地图查找工厂没有任何好处。事实上,这只是浪费。一个简单的开关 [1] 将 远 优越。更重要的是,因为它删除了std::function
中的类型擦除(隐式虚拟多态)。
[1] 事实上,它需要链接if
,或者你可以打开Perfect Hash