用户模板化定义结构的 QList
我可以定义一个 QList 以便它保存模板化结构的集合,每个结构定义在不同的类型上吗?
考虑:
template<typename T>struct AA
{
T value;
}
我可以声明一个 QList 以使其包含 AA 的不同实例吗? 类似于:
struct<int> myIntStruct;
myIntStruct.value = 10;
struct<double> myDobleStruct;
myDoubleStruct = 12.2;
template<typename T>
QList<struct AA<T>> myList;
myList.push_back(myIntStruct);
myList.push_back(myDoubleStruct);
我的意见是 QList 应该包含相同数据类型的实体(即使对于模板化对象),这就是为什么上述操作是非法的。在这种情况下,我可以在 Qt 中使用什么结构来执行类似的操作?
谢谢,
毗湿奴。
Can I define a QList such that it holds a collection of templated structs, with each struct defined on different type ??
Consider:
template<typename T>struct AA
{
T value;
}
Can I declare a QList such that it holds different instances of AA ??
something like:
struct<int> myIntStruct;
myIntStruct.value = 10;
struct<double> myDobleStruct;
myDoubleStruct = 12.2;
template<typename T>
QList<struct AA<T>> myList;
myList.push_back(myIntStruct);
myList.push_back(myDoubleStruct);
My Opinion is that the QList should contain entities of same datatype (even for a templated objects) and that's why the above operation is illegal. In that case what structure can I use in Qt to do an operation like that ??
Thanks,
Vishnu.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
为什么你想要一个容器拥有不同的对象可能是一个设计缺陷。然而,有些语言支持这一点,例如 Smalltalk,它具有包集合的概念,可以包含不同对象类型的混合。 Qt 可能已经有某种包容器类,但我不知道它的存在。
这种在单个容器中混合类型的概念在 C++ 的强类型世界中不太适用。变体对象是最接近的东西,即使这样,也不适用于非整数类型,而不需要创建自己的“超级变体”类,您可以通过子类化 QVariant 然后添加一些位来处理您的结构来完成。
再次问自己一个问题:为什么需要这个功能?在其他地方实现的更简单的解决方案可能会减少对此类容器的需求。
编辑:
QMap
的快速示例,以帮助确定这是否可行。QVariant
处理许多类型,它还具有用于用户定义类型的模板方法setValue
和value>>
。如上面简要所示,您必须使用Q_DECLARE_METATYPE
宏将其注册到QMetaType
并提供默认构造函数,以防value
转换失败。它不支持某些比较运算符,因此我会制作自己的QVariant
和QMetaType
版本,以便与所需的任何额外类型很好地配合,因此感觉更加一致。Why you would want a container to have dissimilar objects is probably a design flaw. However some languages support this such as Smalltalk which has the concept of a Bag Collection that can contain a mix of different object types. Qt may have some sort of bag container class already but I am unaware of it's existence.
This concept of mixed types in a single container does not work so well in the strongly typed world of C++. Variant objects are the closest thing and even then not for non integral types without making your own "super variant" class which you could do by subclassing
QVariant
then adding some bits to handle your structs.Again ask yourself the question why do you need this functionality? A simpler solution implemented elsewhere will probably alleviate the need for such a container.
Edit: Quickie example of
QMap<QString, QVariant>
to help determine if that would work.QVariant
handles a lot of types it also has template methodssetValue
andvalue<>
for user defined types. As shown briefly above you have to useQ_DECLARE_METATYPE
macro to register it withQMetaType
and provide a default constructor in casevalue<>
conversion fails. It won't support certain comparison operators so I would make my own version ofQVariant
andQMetaType
to play nice with any extra types needed so it feels more consistent.模板类不是一个类,它是一个模板。您可以使用它来实例化完全不相关的类,例如
AA
和AA
。为了获得您正在寻找的功能 - 将不相关的类添加到容器 - 您需要一个专门支持添加此类不相关实例的容器,或者您需要将您的对象包装在例如
boost::variant
A template class isn't a class, it's a template. You can use it to instantiate completely unrelated classes, such as
AA<int>
andAA<double>
.In order to get the functionality you're looking for - adding unrelated classes to a container - you need either a container that specifically supports adding such unrelated instances, or you need to wrap your objects in e.g.
boost::variant
你是对的,同一个容器中通常不能有非同质类型。
您可以使用(智能)指针容器、
boost::any
、boost::variant
来解决这个问题,我确信还有其他机制。You're right that you can't generally have non-homogeneous types in the same container.
You can get around that with containers of (smart) pointers,
boost::any
,boost::variant
, and I'm sure other mechanisms.我相信
MyTemplateClass
和MyTemplateClass
被视为单独的数据类型,因此您不能拥有同时包含这两种类型的 QList。不过,你还有选择。如果您只是存储简单的数据类型,请查看 QVariant。它是单一类类型,但它使用联合来保存其中的各种数据类型。而且它是内置的,因为您已经在使用 Qt!
如果您想存储更复杂的东西,多态类可能是正确的选择。然后,您可以拥有一个
MyBaseType*
的 QList,并将需要从列表中调用的所有函数设为virtual
。您甚至可以使 MyBaseType 继承自 QVariant,以便为您处理数据存储。希望这有帮助!
I believe that
MyTemplateClass<int>
andMyTemplateClass<double>
are considered to be separate data types, so you can't have a QList containing both types at once.You've got options, though. If you're just storing simple data types, check out QVariant. It's a single class type, but it uses unions to hold a variety of data types inside it. And it's built-in, since you're already using Qt!
If you're trying to store more complicated things, polymorphic classes are probably the way to go. Then you can have a QList of
MyBaseType*
s, and have all the functions you need to call from the list bevirtual
. You can even make MyBaseType inherit from QVariant, so the data storage is taken care of for you.Hope this helps!