[英]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;
}
有点不雅观,如果您只有几个字段,则可以合理地让getCsvA
和getCsvB
调用getCsv(A_or_B a_or_b)
函数,给定enum A_or_B { A, B };
,然后当您遍历getCsv
时在collMap
说int 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.