是否可以使用基类类型专门化 C++ 模板?

问题描述 投票:0回答:1
template<typename T>
struct is_message : std::false_type {};


template<typename T>
class Publisher {
static_assert(is_message<T>::value, "This message type is not supported");
public:
  void Publish(T& msg) {}
};

之前的代码是来自第三方库的简化草图(ROS2 很简陋,我们不应该更改此代码库), 它使用类型特征

is_message
将消息类型限制为其生成的 IDL C++ 消息,该消息生成代码来专门化先前的类型特征模板,如下所示:

class GeneratedIdlMessageX {
public:
};
template<> struct is_message<GeneratedIdlMessageX> : std::true_type {};

然后用户可以像这样删除正在工作的发布者:

#include <ros2_headers.h>
#include <ros2idl_generated_message.h>

Publisher<GeneratedIdlMessageX> publisher;

现在的问题是我们也想支持 protobuf 消息,但我们无法修改 protobuf IDL 代码生成来添加此专门化。 因此,我们必须在每个 protobuf 消息发布声明上手动添加此专业化,如下所示:

#include <ros2_headers.h>
#inlcude <protobuf_generated_message.h>

template<> struct is_message<ProtoBufMessageY> : std::true_type {};

Publisher<ProtoBufMessageY> publisher;

怎样才能省掉这个烦人的工作呢?

一个直接的想法是引入一个预定义的通用标头,它将所有 protobuf 生成的消息专门用于发布者用户。 考虑到所有protobuf生成的c++消息都是从

MessageLite
继承的,我尝试直接专门化基类,显然它不起作用:

// of course this won't work
template <> struct is_message<protobuf::MessageLite> : std::true_type{};

现在我因为无法修改第三方(ros2)和 protobuf IDL 生成代码而陷入困境,感谢任何帮助

c++ templates protocol-buffers ros2
1个回答
0
投票
template <std::derived_from<protobuf::MessageLite> T>
struct is_message<T> : std::true_type {};
© www.soinside.com 2019 - 2024. All rights reserved.