繁体   English   中英

基于成员收集的模板功能

[英]Template function for collection based on member

我有以下结构

struct Obj
{
  int a;
  int b;
};
class ObjCollection
{
   map<int,Obj> collMap;
 public:
   string getCsvA();
   string getCsvB();
};

getCsvA返回collMap对象中所有a值的collMap 对于所有b值, getCsvB返回相同的值。

有没有办法为该功能建立模板? 对我来说变得复杂的原因是,我无法从此类之外(即从我的客户代码中)传递我要为其生成csv的成员的地址。 有没有办法做到这一点? 注意:我不能使用C ++ 11。

看起来您需要一个函数作为getCsv的参数,而不是模板:

将函数声明为string getCsv(int (*selectMember)(Obj)) 此外,在getCsvA使用[...].a地方都使用getCsvA selectMember([...])

现在,您可以调用getCsv提供一个返回Obj正确字段的方法,例如:

int selectA(Obj o)
{
    return o.a;
}

有点不雅观,如果您只有几个字段,则可以合理地让getCsvAgetCsvB调用getCsv(A_or_B a_or_b)函数,给定enum A_or_B { A, B }; ,然后当您遍历getCsv时在collMapint value = (a_or_b == A) ? iterator->a : iterator->b; int value = (a_or_b == A) ? iterator->a : iterator->b; ,然后将该 value放入csv字符串中。 与担心成员数据,函子或模板的指针相比,它更容易:当您对这种级别的编程感到满意时,则可以担心更抽象的方法(希望您那时可以使用C ++ 11,因为lambda非常适合这个)。

您实际上拥有的代码框架看起来还不错。 参数化不需要参数化的东西通常是一个坏主意。 模板是最强大的方法,但实际上应该同样谨慎地使用它们。

通过添加参数,您将为错误代码(错误的函数指针,空指针等)增加更多机会。 由于通常必须在运行时解决执行代码的问题,因此使用函数指针或虚拟方法还会给编译器优化带来更多困难。

如果您使用的是C ++ 11而不是C ++ 03,那么使用std::tuple而不是裸struct可能很有意义,并且您将获得模板化功能作为奖励。

#include <utility>

template<typename... Ts>
class TupleCollection {

 public:

   template<std::size_t I>
   std::string getCsv() {

     for (const auto& p : collMap) {

       std::string v = static_cast<std::string>(std::get<I>(p.second));
       ...
      }
  }

  private:

    std::map<int, std::tuple<Ts...>> collMap;

};

然后以编译时安全的方式获取相关字段的CSV将是

tc.getCSV<0>();
tc.getCSV<1>();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM