假设我有一个模板函数,它通过指向成员的指针在结构中设置数据:
struct S
{
double d;
unsigned int u;
};
struct A
{
S s, s2;
float f;
int i;
};
template<typename Stream, typename Class, typename Type>
void read(Stream& s, Class& out, Type Class::*member)
{
s >> out.*member;
}
现在对于f
和a
这样的常规成员,我可以在struct A
的任意实例上使用此函数:
#include <sstream>
int main(int, char**)
{
std::stringstream stream;
A a;
stream.clear(); stream.str("1");
read(stream, a, &A::i);
stream.clear(); stream.str("1.5");
read(stream, a, &A::f);
stream.clear(); stream.str("2");
printf("%i\n", a.i);
printf("%f\n", a.f);
}
但是有没有办法以类似的方式访问A::s
或A::s2
的成员,而为每个复合成员编写一个新的,实际上相同的函数({{1 },s
等)?
据我所知,成员的指针不存在,但是有替代解决方案吗? (它必须处理s2
或struct
的任意实例,类似于上面的指针到成员解决方案的工作方式,并且不需要class
或{{1}中的其他方法}})。
稍微澄清一下这个问题(另请参阅this answer中的评论):在实际代码(配置文件阅读器)中,调用者使用第一个字符串在地图中查找并且实际上并不知道当前正在读取的内容(使用第二个字符串),因为绑定了指向成员的参数。此外,地图初始化一次并用于A
的多个实例,因此指向成员的指针。
请注意c ++ 03标签。因此,c ++ 11 lambdas不是一种选择。
答案 0 :(得分:1)
不确定我是否解决了问题。
正如你可以通过PTM到达成员i,f你可以用S做同样的事情。你不需要单独的函数来访问s和s2:单个函数将使用类型为S A::*
的额外参数。
或者如果类型必须是可变的,您可以将读取函数扩展为:
template<typename Stream, typename Class, typename Type, typename Class2, typename Type2>
void read(Stream& s, Class& out, Type Class::*member, Type2 Class2::*member2)
{
s >> ((out.*member).*member2);
}
并像read(stream, a, &A::s, &S::u);
(我手边没有编译器来测试它,可能需要一些修补)