助推凤凰地图new_

map of boost phoenix new_?

本文关键字:new 地图 凤凰      更新时间:2023-10-16

我有以下工厂函数:

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)。但这是样板文件,似乎足够简单,boost必须有一个很好的解决方案…

Phoenix是惰性函子的实用程序。

这里不需要任何表达式模板(这里没有任何表达式模板)。

因此,你可以创建自己的工厂方法模板:
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]far优越。更重要的是,它删除了std::function中的类型擦除(隐式虚拟多态性)。

[1]实际上,它需要链接if s,或者您可以打开完美散列