存储对具有不同类的对象成员变量的引用
我正在尝试创建一个 Container 类,在其中我可以使用该对象成员变量作为其标识符来从容器中检索对象。 但是我收到编译错误,因为我试图存储对对象成员变量的指针(?)/引用
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
I am trying to create a Container class where I can retrieve an object from the container by using that objects member variable as its identifier. But I get a compile error because I am trying to store a pointer(?)/reference to the objects member variable
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
C++ 中不允许声明模板数据成员(不要与定义静态成员时使用的模板语法混淆)。实现这一目标的最佳方法是,
Declaring a template data member is not allowed in C++ (not to confuse with template syntax used while defining a static member). The best way to achieve is,
声明一个tempate数据成员?这是 C++ 不允许的。我不能给你建议任何替代方案,因为我实际上不明白你到底想做什么。
为什么不首先尝试使用标准库提供的容器呢?您是否见过
std::vector
、std::list
、std::map
等,以及来自的泛型函数?算法>
?Declaring a tempate data member? That is not allowed by C++. And I cannot you suggest any alternative, because I don't actually understand what exactly you're trying to do.
Why don't you first try using containers provided by the Standard Library? Have you seen
std::vector
,std::list
,std::map
etc, along with generic functions from<algorithm>
?在下面,您所要求的内容有两种变体:第一个成员是模板参数,第二个成员在构建地图时作为参数传递......
基本上您需要移动到至少将成员类型作为模板参数输出,因为需要它才能生成映射的 C++ 代码。您可以在运行时决定要用作键的成员(第二个版本),但其类型必须在编译时固定。
相反,如果您想要用作键的实际成员在编译时已知,则可以将成员指针分解为模板参数(第一个版本),从而生成更有效的代码(但是为每个不同的成员创建一个新类 - 因此增加编译代码的大小)。
In the following there are two variations of what you are asking for: the first in which the member is a template parameter, and the second in which the member is instead passed as argument when building the map...
Basically you need to move at least the member type out as a template parameter because that is needed to be able to generate the C++ code of the map. You can decide at runtime what is the member you want to use as key (second version), but its type must be fixed at compile time.
If instead even the actual member you want to use as key is known a compile time then the member pointer can be factored out as a template parameter (first version), generating more efficient code (however creating a new class for every different member - thus increasing compiled code size).
您可以通过声明这样的成员类型来逃脱。
you can get away by declaring a member type like this.