我正在做一个简单的项目,其中有发布者从一个数据源中读取数据并构建事件供订阅者处理。
一个事件将有一个唯一的数据ptr,订阅者将拥有一个共享的事件ptr。
我希望有一个事件的通用接口(interface),以便订阅者可以订阅任意数据发布者。
但是发布者只能发布一种类型的数据。
#include <memory>
#include <iostream>
class Data
{
};
class ChildData : public Data
{
};
template<typename T>
class Event
{
std::unique_ptr<T> _data;
};
void someFunc(Event<Data> event)
{
std::cout << "hello Word" << std::endl;
}
int main()
{
Event<ChildData> event();
someFunc(event);
return 0;
}
但我收到以下编译器错误
/home/rory/dev/cpp_sandbox/main.cpp: In function ‘int main()’:
/home/rory/dev/cpp_sandbox/main.cpp:27:19: error: could not convert ‘event’ from ‘Event<ChildData> (*)()’ to ‘Event<Data>’
someFunc(event);
^
CMakeFiles/example.dir/build.make:62: recipe for target 'CMakeFiles/example.dir/main.cpp.o' failed
make[2]: *** [CMakeFiles/example.dir/main.cpp.o] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/example.dir/all' failed
make[1]: *** [CMakeFiles/example.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
这种事情在 C++ 中可能吗?
最佳答案
有问题的行是这样的:
Event<ChildData> event();
根据 most vexing parse规则,这被解释为函数声明。如果您的
Event
,则可以省略括号。类具有初始化所有成员的默认构造函数。否则使用统一初始化语法:Event<ChildData> event{};
此外,您可能必须使用
std::move
通过event
至someFunc
, 自 Event
不可复制,因为 std::unique_ptr
数据成员。此外,您必须实现从 Event<ChildData>
的转换。至Event<Data>
,这是 someFunc
所必需的.I want to have a common interface to an event so a subscriber can subscribe to an arbitrary Data publisher. But a publisher can publish only one type of Data.
从这个描述来看,它看起来像
Event
模板是多余的。 Data
的通用接口(interface)后代可以在Data
中描述类本身,因此除非需要将事件与数据分开,否则只处理数据会更容易。为了区分不同的事件类型,您可以使用枚举。
enum class EventType
{
A,
B,
C
};
class Data
{
private:
const EventType m_type;
protected:
explicit Data(EventType type) : m_type(type) {}
public:
virtual ~Data() = default;
// Prohibit copying to avoid accidental slicing
Data(Data const&) = delete;
Data& opreator= (Data const&) = delete;
EventType get_type() const { return m_type; }
};
class ChildData :
public Data
{
public:
ChildData() : Data(EventType::A) {}
};
void receive(std::unique_ptr< Data > event)
{
switch (event->get_type())
{
case EventType::A:
{
std::unique_ptr< ChildData > child_event{ static_cast< ChildData* >(event.release()) };
// Process ChildData
}
break;
case EventType::B:
// ...
case EventType::C:
// ...
}
}
void publish(std::unique_ptr< Data > event);
int main()
{
std::unique_ptr< ChildData > event{ new ChildData() };
// Fill ChildData event
publish(std::move(event));
}
关于c++ - C++中模板类型中的类层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60137988/