使用带有类型化角色的容器会产生 "incomplete type" 错误

Using containers with typed actors give "incomplete type" errors

当我向键入的消息添加容器时,我收到“类型不完整”的错误消息。这是一个简单的例子。请注意“display_behavior”消息中的最后一个参数是一个字符串吗?这个演员编译和运行得很好。

using DisplayActor = caf::typed_actor<
    caf::result<void>(display_behavior, time_point<system_clock>, string)>;

class DisplayState {
private:
    shared_ptr<Displayable> displayable_;

public:
    explicit DisplayState(std::shared_ptr<Displayable> displayable) :
        displayable_(displayable) {}

    DisplayActor::behavior_type make_behavior() {
        return {
            [this](display_behavior, time_point<system_clock> quackTime, string behavior) {
                displayable_->displayBehavior(quackTime, behavior);
            }
        };
    }
};

using DisplayImpl = DisplayActor::stateful_impl<DisplayState>;

现在我用向量替换字符串参数:

using DisplayActor = caf::typed_actor<
    caf::result<void>(display_behavior, time_point<system_clock>, vector<string>)>;

class DisplayState {
private:
    shared_ptr<Displayable> displayable_;

public:
    explicit DisplayState(std::shared_ptr<Displayable> displayable) :
        displayable_(displayable) {}

    DisplayActor::behavior_type make_behavior() {
        return {
            [this](display_behavior, time_point<system_clock> quackTime, vector<string> behavior) {
                //displayable_->displayBehavior(quackTime, behavior);
            }
        };
    }
};

using DisplayImpl = DisplayActor::stateful_impl<DisplayState>;

我收到以下错误:

我是不是做错了什么?

如果您看到此类错误,通常意味着您使用的类型没有分配给它的类型 ID。

CAF 使用类型 ID 生成消息的元数据。基于这个元数据,CAF 然后可以实现“类型切换”以根据签名自动调度消息处理程序。从 0.18.5 开始,CAF 将类型 ID 分配给标准库的某些类型,例如 std::string(参见 https://github.com/actor-framework/actor-framework/blob/0.18.5/libcaf_core/caf/type_id.hpp#L375)。

但是,std::vector<std::string> 默认没有类型 ID。这意味着您的应用程序需要分配一个。样板代码看起来有点像这样:

CAF_BEGIN_TYPE_ID_BLOCK(my_types, first_custom_type_id)

  CAF_ADD_TYPE_ID(my_types, (std::vector<std::string>))

CAF_END_TYPE_ID_BLOCK(my_types)

稍后您还需要确保初始化 run-time 类型信息。如果您使用 CAF_MAIN 那么它只是:

CAF_MAIN(caf::id_block::my_types)

如果您不使用宏,则需要在 开始 actor_system 之前添加这些行 (最好是 main 中的第一件事):

caf::init_global_meta_objects<caf::id_block::my_types>(); // custom types
// ... module types, e.g., caf::io::::init_global_meta_objects() ...
caf::core::init_global_meta_objects(); // default types

当前 (0.18.5),手册讨论了 Configuring Actor Applications 下的类型 ID。它出现在本节中主要是出于历史原因,因为添加了用于通过 actor-system 配置的 run-time 类型信息。也许类型 ID 应该有自己的部分,或者至少移至手册的“类型检查”部分。

I am still a bit confused though because this page shows how to write an inspect overload and the point_3d field has a vector member variable.

如果您希望在消息中单独发送该类型,则需要该类型的类型 ID。这是模式匹配/类型开关所必需的。序列化程序可以处理 std::vector 并且不需要类型 ID。他们在 inspect API 上运行。美好的一天,C++ 希望带有(静态)类型反射,并且大多数 inspect 重载可以由 CAF auto-generated。