包装器功能可以重构吗

时间:2018-06-21 19:19:58

标签: c++

我有一组C ++函数,它们均接受同一类型集(以下示例中的TypeATypeBTypeC)中的一个类型作为模板参数。为了简化将这些函数公开给python的工作,我想为每个函数定义一个函数,该函数的类型不是模板参数,而是字符串参数,如下所示:

template<typename dataType>
int function(int arg)
{
    ...
}

int function(int arg, string type)
{
    if (type == "type_A")
    {
        return function<TypeA>(arg);
    }
    else if (type == "type_B")
    {
        return function<TypeB>(arg);
    }
    else if (type == "type_C")
    {
        return function<TypeC>(arg);
    }
    else
    {
        std::cerr << "Invalid type!" << std::endl;
        exit(1);
    }
}

此刻,我以这种方式包装了所有函数,但是这导致了很多代码重复,所以我想知道是否有更好的方法,也许使用预处理器指令?

1 个答案:

答案 0 :(得分:4)

减少if/else逻辑的一种方法是存储std::function对象的映射,并使用该映射进行正确的调用。

int function(int arg, std::string type)
{
   using FMap = std::map<std::string, std::function<int(int)>>;
   static const FMap fmap{{"type_A", [](int arg) { return function<TypeA>(arg); }},
                          {"type_B", [](int arg) { return function<TypeB>(arg); }},
                          {"type_C", [](int arg) { return function<TypeC>(arg); }}};

   auto iter = fmap.find(type);
   if ( iter != fmap.end() )
   {
      return iter->second(arg);
   }

   std::cerr << "Invalid type!" << std::endl;
   exit(1);
   return 0;
}

如果愿意重命名功能模板,则可以简化构造功能图的代码。

template <typename T>
int fun_2(int arg) { ... }

int function(int arg, std::string type)
{
   using FMap = std::map<std::string, std::function<int(int)>>;
   static const FMap fmap{{"type_A", fun_2<TypeA>},
                          {"type_B", fun_2<TypeB>},
                          {"type_C", fun_2<TypeC>}};

   auto iter = fmap.find(type);
   if ( iter != fmap.end() )
   {
      return iter->second(arg);
   }

   std::cerr << "Invalid type!" << std::endl;
   exit(1);
   return 0;
}