存储对具有不同类的对象成员变量的引用
Store a reference to an objects member variable with a different class
我正在尝试创建一个容器类,我可以通过使用对象成员变量作为其标识符从容器中检索对象。但是我收到编译错误,因为我正在尝试存储指针(?/对对象成员变量的引用
template <typename Object>
class Container
{
private:
template <typename dataType>
dataType Object::* memberVariable; // error here "data member 'memberVariable' cannot be a member template"
template <typename dataType>
std::map <dataType, Object*> instanceVarMap; // what would be more efficient; a Map or unordered_map? I heard that
std::map <unsigned int, Object*> instanceIntMap; // ...unordered_maps use more memory & Maps are better when integers are the keys
public;
template <typename dataType>
Collection( dataType Object::*nMemberVariable )
{
memberVariable = nMemberVariable;
}
template <typename dataType>
Object* operator[] ( dataType nParam )
{
// do I need to check whether the element already exists or does
// stl already do this for me?
if ( instanceVarMap.find(nParam) == instanceVarMap.end() )
{
return NULL;
}
return instanceVarMap[ nParam ];
}
Object* operator[] ( unsigned int nParam )
{
if ( instanceIntMap.find(nParam) == instanceIntMap.end() )
{
return NULL;
}
return instanceIntMap[ nParam ];
}
void store( Object* o )
{
if ( o==NULL || instanceMap.contains(o->memeberVariable) != instanceMap.end() ) { return; }
instanceIntMap.insert( o->ID, o );
instanceVarMap.insert( o->memberVariable, o ); // is this the correct way I get the objects member variable? o->memberVariable
}
};
// I am doing this so I can use the class like so
struct FoodItem
{
unsigned int ID;
string name;
double price;
};
Collection <FoodItem*> foodCol( &FoodItem::name );
// after storing some FoodItems in foodCol, I can retreive a FoodItem either
// by their ID or their name
FoodItem* f = foodCol["coffee"]; // find FoodItem by their member variable 'name'
FoodItem* g = foodCol[1]; // find FoodItem by their ID var
C++中不允许声明模板数据成员(不要与定义静态成员时使用的模板语法混淆)。最好的实现方法是,
template <typename Object, typename dataType> // <-- Add dataType here
class Container
{
private:
dataType Object::* memberVariable; // use 'dataType' simply
// ...
};
template <typename dataType>
dataType Object::* memberVariable; // error
声明临时数据成员?这是C++不允许的。 我不能提出任何替代方案,因为我实际上不明白你到底想做什么。
为什么不先尝试使用标准库提供的容器? 您是否见过std::vector
,std::list
,std::map
等,以及<algorithm>
的泛型函数?
在下面,您要求的内容有两种变体:第一种是成员是模板参数,第二种是在构建地图时将成员作为参数传递的......
#include <map>
#include <string>
#include <iostream>
template<typename Object, typename MemberType, MemberType Object::*member>
struct MemberMap
{
std::map<MemberType, Object *> mmap;
Object * operator[](const MemberType& mv) const
{
typename std::map<MemberType, Object *>::const_iterator i = mmap.find(mv);
return i == mmap.end() ? NULL : i->second;
}
void store(Object *o)
{
if (o && mmap.find(o->*member) == mmap.end())
mmap[o->*member] = o;
}
};
template<typename Object, typename MemberType>
struct MemberMapByInst
{
MemberType Object::*member;
std::map<MemberType, Object *> mmap;
MemberMapByInst(MemberType Object::*member) : member(member)
{
}
Object * operator[](const MemberType& mv) const
{
typename std::map<MemberType, Object *>::const_iterator i = mmap.find(mv);
return i == mmap.end() ? NULL : i->second;
}
void store(Object *o)
{
if (o && mmap.find(o->*member) == mmap.end())
mmap[o->*member] = o;
}
};
struct Foo
{
std::string name;
Foo(const std::string& name) : name(name)
{
}
};
int main()
{
Foo foo1("This is a test");
Foo foo2("This is another test");
MemberMap<Foo, std::string, &Foo::name> namemap;
namemap.store(&foo1);
namemap.store(&foo2);
MemberMapByInst<Foo, std::string> namemap2(&Foo::name);
namemap2.store(&foo1);
namemap2.store(&foo2);
std::cout << (namemap["This is a test"] != NULL) << std::endl;
std::cout << (namemap["What about this?"] != NULL) << std::endl;
std::cout << (namemap2["This is a test"] != NULL) << std::endl;
std::cout << (namemap2["What about this?"] != NULL) << std::endl;
return 0;
}
基本上,您至少需要将成员类型作为模板参数移出,因为需要能够生成映射的C++代码。您可以在运行时决定要用作键的成员是什么(第二个版本),但其类型必须在编译时修复。
相反,如果即使是要用作键的实际成员在编译时也是已知的,则可以将成员指针分解为模板参数(第一个版本),从而生成更有效的代码(但是为每个不同的成员创建一个新类 - 从而增加编译的代码大小)。
您可以通过
像这样声明成员类型来摆脱困境。
struct MyObject
{
int Variable;
typedef int MyObject::* ObjectVariablePtrType;
};
template<typename Object>
class Container
{
typename Object::ObjectVariablePtrType memberVariable;
};
相关文章:
- 指向设备对象成员的指针
- 访问由unique_ptr传递的对象成员
- 引用对象成员函数的成员函数
- 将 C# 对象(包含静态对象成员)作为参数传递给 C++/CLI 程序
- Lua C API - 从C++分配和使用类的对象成员
- Rapidjson 遍历并获取复杂 JSON 对象成员的值
- 类对象成员变量在调用函数时不会更改
- 对象成员变量还是继承
- C++多态性:有没有办法找到对象成员函数的地址?
- 重载对象成员的比较运算符
- 获取未初始化对象成员的地址是否定义良好?
- 在优先级队列被推送到队列后,如何编辑对象成员
- 为什么在这里调用析构函数,以及在调用该对象析构函数后如何调用对象成员函数?
- 通过 std::bind 从对象成员检索值
- 保留对象成员变量的本地副本
- 有没有办法为静态对象成员定义一个符合开关标准的常量?
- 没有默认构造函数的对象成员的 wig setter
- 对象成员数组C++默认初始化
- 如何在数组中添加对象成员
- 使用聚合创建和关联两个不同的对象成员