我正在努力实现与字符串键关联的成员变量指针的映射。
所有变量的范围都来自基类“BaseA”
当从映射中访问变量时,只需要使用基类方法(示例中的 getDesc() ),因此不需要检索原始类型。
该代码在GNU g ++ 6.2.1下编译并运行,但根据我读到的内容,reinterpret_cast的使用不可移植,并且可能无法与其他编译器一起使用。
它是否正确?或者这段代码符合C++标准吗?
有没有其他方法可以在不使用reinterpret_cast的情况下做到这一点?
一项要求是“Vars”必须可以使用默认的复制构造函数和复制赋值实现进行复制。
示例代码:
#include <iostream>
#include <sstream>
#include <map>
#include <typeinfo>
using namespace std;
struct BaseA
{
virtual string getDesc() = 0;
};
struct A1 : BaseA
{
string getDesc() override { return "This is A1"; }
};
struct A2 : BaseA
{
string getDesc() override { return "This is A2"; }
};
struct Vars
{
A1 a1;
A2 a2;
map< string, BaseA Vars::* > vars;
Vars()
{
vars["A1_KEY"] = reinterpret_cast<BaseA Vars::*>(&Vars::a1);
vars["A2_KEY"] = reinterpret_cast<BaseA Vars::*>(&Vars::a2);
}
BaseA& get( const string& key )
{
auto it = vars.find( key );
if ( it != vars.end())
{
return this->*(it->second);
}
throw std::out_of_range( "Invalid variable key:[" + key + "]");
}
};
int main()
{
Vars v;
cout << "a1 description :" << v.get("A1_KEY").getDesc() << endl;
cout << "a2 description :" << v.get("A2_KEY").getDesc() << endl;
return 0;
}
是的,有很少有保证 http://en.cppreference.com/w/cpp/language/reinterpret_cast关于什么reinterpret_cast
会做,并且从一个指针到成员的转换到另一个不是其中之一(除非您然后转换回原始类型,这并不能真正帮助您)。
执行此操作的安全且简单的方法是使用std::function
:
struct Vars
{
A1 a1;
A2 a2;
map< string, std::function<BaseA&(Vars&)> > vars;
Vars()
{
vars["A1_KEY"] = &Vars::a1;
vars["A2_KEY"] = &Vars::a2;
}
BaseA& get( const string& key )
{
auto it = vars.find( key );
if ( it != vars.end())
{
return it->second(*this);
}
throw std::out_of_range( "Invalid variable key:[" + key + "]");
}
};
请注意,如果您从不需要vars
字典要改变,你可以把它变成static const
成员。 (这意味着您需要在源文件中的类外部定义和初始化它。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)