模板类 C++ /Qt
我有一个应用程序将接收来自另一个应用程序的消息。这些消息将是 XML 格式的字符串,并且它们将包含
标记。消息类型将将此消息标识为内部消息的类型。以下代码显示了我的内部消息结构。
namespace
Application1{
enum ApplicationAttributes{
ApplicationName = 1000,
Start,
Stop,
Pause,
Save,
Discard,
SelectRunway,
DoAlignment,
RedoAlignment,
AlignmentOK,
DoCalibrationStage1,
SetCalibrationStage1,
SetCalibrationStage2,
SetCalibrationStage3,
CancelCalibration,
CalibrationOK
};
struct Alignment{
int x;
int y;
int error;
};
struct Calibration{
int x;
int y;
int error;
};
}
对齐和校准是两种内部消息结构。
我想做的是构建一个“消息解释器”,它将接收 XML 字符串,对其进行解码并返回上面显示的任何一个结构;因此,如果
是“alignment”,消息解释器将构建一个对齐结构并返回该结构。
所以最终,我试图创建一个模板函数,它可以根据我从
读取的内容返回任意结构。
我的目标明确吗?我的方法正确吗?
让我知道是否应该澄清,或者是否应该采取不同的方法。
I have an application which will be receiving messages from another application. These messages will be XML fomatted strings, and they will contain a <messageType>
tag. The message type will identify this message as a type of internal message. The following code shows my internal message structures.
namespace
Application1{
enum ApplicationAttributes{
ApplicationName = 1000,
Start,
Stop,
Pause,
Save,
Discard,
SelectRunway,
DoAlignment,
RedoAlignment,
AlignmentOK,
DoCalibrationStage1,
SetCalibrationStage1,
SetCalibrationStage2,
SetCalibrationStage3,
CancelCalibration,
CalibrationOK
};
struct Alignment{
int x;
int y;
int error;
};
struct Calibration{
int x;
int y;
int error;
};
}
alignment and calibration are the two internal message structures.
What I'm trying to do is build a 'message interpreter' which will receive an XML string, decode it and return any one of the structs shown above; so if the <messageType>
is 'alignment', the message interpreter will build an alignment struct, and return that.
So ultimately, I'm trying to make a template function, which can return an arbitrary struct, based on what i read in from <messageType>
.
Are my objectives clear? is my approach the right one?
Let me know if I should clarify, or if I should take a different approach.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我不认为模板函数有意义。您的输入始终是一个字符串,而 C++ 无法仅根据返回类型来区分函数签名 - 所以我不知道模板有何帮助 - 类型参数是什么?
我建议让你的函数成为一个普通的函数,解析出 messageType 并根据它分配一个结构 - 你可以使用任何你想要的结构。
诀窍是(在我看来)从同一个空基类派生所有内部消息类 - 然后您可以从函数返回指向该基类的指针,并且它将保存创建的任何类型。
最好在 std::pair 中返回一个枚举和指针,您可以使用它来确定创建的正确派生类型,这样您就可以使用 static_cast 将结果直接转换为正确的派生类型。
I don't believe a template function makes sense. Your input is always going to be a string, and C++ can't differentiate function signatures based on return type alone - so I don't know how a template would help - what would the type argument be?
I'd suggest making your function a normal one that parses out the messageType and allocates a struct based on it - you can use whatever constructs you want for this.
The trick would be (in my mind) to derive all of your internal-message-classes from the same empty base class - you could then return a pointer to that base class back from your function, and it will hold whatever type got created.
It be a good idea to return an enumeration along with the pointer in a std::pair which you can use to determine the correct derived type that was created, that way you can cast the result directly to the correct derived type with a static_cast.
据我了解,您的结构在应用程序中是已知的,那么这个保存变体怎么样:(
未经验证而编码以给您想法)
这无需多态性即可工作(我在类似 LISP 的语言的编译器中使用此模式,其中多态树会导致更复杂的代码)。如果您更喜欢的话,您可以将其更改为返回“alignment_x()”等。
完全动态的结构是不可能的,并且试图接近的解决方案将相当复杂。使用最易于维护的解决方案。
As I understand it your structures are known within the application, so what about this save variant:
(coded without verification to give you the idea)
This works without polymorphism (I use this pattern in a compiler for a LISP like language, where polymorphic trees would result in more complicated code). You can change it to return "alignment_x()" and so on, if you like that more.
Fully dynamic structures are not possible, and solutions that try to come near will be rather complicated. Use the most-maintainable solution.
如果您为每种类型编写一个工厂函数/函子,则可以将其与
messageType
关联起来(map
就足够了),但是要做什么返回?如果您不介意顶级解码器取决于所有可能的消息类型,则可以返回某种可区分的联合或
boost::variant
。但是,解码器将如何处理这个返回值呢?如果它只是打开类型并在每种情况下调用特定于类型的回调,则可以通过直接将回调函数/函子附加到工厂来反转控制。
然后解码器不会返回任何内容,它只是构造消息 struct 并将其直接传递给处理程序。
简单的实现(好吧,打字比我想象的要多):
If you write a factory function/functor for each type, you can associate that with the
messageType
(map<string, Factory*>
will be sufficient), but what to return?You can return some kind of discriminated union, or
boost::variant
, if you don't mind the top-level decoder depending on all possible message types.But, what is the decoder going to do with this return value? If it just switches on the type and calls a type-specific callback in each case, you could invert control by attaching a callback function/functor to the factory directly.
Then the decoder doesn't return anything, it just constructs the message
struct
and passes it directly to a handler.Simple implementation (OK, that was more typing than I thought):
使用dynamic_cast 将其转换为您的类
使用 QMetaObject::newInstance,因此您可以创建一个 QObject*,然后可以在您的 XML 解析代码中
:事情就会解决。
using QMetaObject::newInstance, so you can create a QObject* that can be converted afterwards to your class using dynamic_cast
then, in your XML Parsing Code:
And things will work out.