我有以下结构
struct Obj
{
int a;
int b;
};
class ObjCollection
{
map<int,Obj> collMap;
public:
string getCsvA();
string getCsvB();
};
getCsvA
会返回a
对象中所有collMap
值的csv。 getCsvB
为所有b
值返回相同内容。
有没有办法模板化这个功能?它对我来说变得复杂的原因是我不能从我的客户端代码之外传递我想要为其生成csv的成员的地址。有没有办法做到这一点? 注意:我不能使用C ++ 11。
答案 0 :(得分:0)
这看起来你需要一个函数作为getCsv
的参数,而不是模板:
将函数声明为string getCsv(int (*selectMember)(Obj))
。此外,只要在selectMember([...])
中使用[...].a
,就可以使用getCsvA
。
现在,您可以致电getCsv
,提供返回Obj
的正确字段的方法,例如:
int selectA(Obj o)
{
return o.a;
}
答案 1 :(得分:0)
虽然有点不优雅,但如果您只是几个字段,则可以合理地getCsvA
和getCsvB
调用getCsv(A_or_B a_or_b)
函数,给定enum A_or_B { A, B };
,然后如果您正在getCsv
说collMap
,那么您将{em> int value = (a_or_b == A) ? iterator->a : iterator->b;
放入您的csv字符串中value
。比担心成员数据,仿函数或模板的指针更容易:当您对这种级别的编程感到满意时,您可以担心更抽象的方法(希望您随后可以使用C ++ 11,如lambdas对此很好。)
答案 2 :(得分:0)
你实际上看起来没问题的代码框架。参数化参数化所需的事情通常是一个坏主意。模板是最强大的方式,但它们应该在相同的判断下使用。
通过添加参数,您可以为错误的代码添加更多机会(错误的函数指针,空指针等)。使用函数指针或虚方法也会使编译器在优化时遇到更多困难,因为执行代码通常必须在运行时解析。
如果您使用的是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>();