CAF:至少有一种类型没有ID-在Linux上编译,但在Windows上没有



我有一个使用C++actor框架和Cmake的概念验证示例,问题是它在Linux上运行良好,但在Windows上遇到了CAF问题。所提供的CAF示例在两个平台上都可以很好地编译,但我不明白为什么我的概念验证示例(Duck Party(会出错。不幸的是,你需要相当多的代码来重新生成,这里是回购:

https://github.com/dylan-baros/duck_party

我在Windows上看到的错误是:

严重性代码描述项目文件行禁止显示状态错误C2338 static_assert失败:"至少有一个类型没有ID,确实有你忘了通过宣布CAF_ADD_TYPE_ID?'DuckParty C:\Users\dbaros\Documents\Repos\duck_party\build_deps\caf src\libcaf_core\caf\mixin\sender.hpp 73

复制

使用Visual Studio 2022社区版(Visual Studio 17 2022(

  1. 克隆repo
  2. 导航到根目录
  3. mkdir构建
  4. cd构建
  5. cmake
  6. cmake——构建。(或者使用Visual Studio导航到解决方案并生成(

我还在example文件夹中包含了一个提供的CAF示例(helloworld(,该示例使用cmake构建良好。

我尝试了什么

一开始我以为可能是CMake,但我想我已经排除了这种可能性,因为helloworld示例使用编译的caf库和CMake构建得很好。我尝试为CustomMessages.h中定义为原子的类型添加CAF_ADD_TYPE_ID,但我得到一个错误,即它们已经被定义。

在触发此编译器错误的行中,您正在尝试发送std::chrono::system_clock::time_point。这就是CAF所抱怨的,因为该类型没有分配类型ID。无论是默认情况下的CAF,还是通过CAF_ADD_TYPE_ID在您的应用程序中。

我无法告诉你为什么这对你来说在Linux上有效,也许GCC或Clang对系统时钟类型的定义意外地与Linux上的caf::timestamp匹配。

在任何情况下,caf::timestamp都是在CAF中发送时间戳的可移植方式,并且默认情况下会宣布此类型(即,具有类型ID(。

我得到了使用以下更改编译的示例:

diff --git a/source/DuckParty/CMakeLists.txt b/source/DuckParty/CMakeLists.txt
index fdf749b..6cdb857 100644
--- a/source/DuckParty/CMakeLists.txt
+++ b/source/DuckParty/CMakeLists.txt
@@ -16,7 +16,7 @@ target_include_directories(DuckParty
)

target_link_libraries(DuckParty
-    PRIVATE CAF::internal CAF::core duck_classes pthread
+    PRIVATE CAF::internal CAF::core duck_classes
)


diff --git a/source/DuckParty/DisplayActor.h b/source/DuckParty/DisplayActor.h
index 73a8b77..ae8ad4e 100644
--- a/source/DuckParty/DisplayActor.h
+++ b/source/DuckParty/DisplayActor.h
@@ -9,7 +9,7 @@
#include "Displayable.h"

using DisplayActor = caf::typed_actor<
-   caf::result<void>(display_behavior, std::chrono::time_point<std::chrono::system_clock>, std::string)>;
+   caf::result<void>(display_behavior, caf::timestamp, std::string)>;

class DisplayState {
public:
@@ -20,8 +20,10 @@ class DisplayState {

DisplayActor::behavior_type make_behavior() {
return {
-               [this](display_behavior, std::chrono::time_point<std::chrono::system_clock> quack_time, std::string behavior) {
-                   displayable_->DisplayBehavior(quack_time, behavior);
+               [this](display_behavior, caf::timestamp quack_time, std::string behavior) {
+               using sys_dur_t = std::chrono::system_clock::duration;
+                   auto sys_time = std::chrono::time_point_cast<sys_dur_t>(quack_time);
+                   displayable_->DisplayBehavior(sys_time, behavior);
}
};
}
diff --git a/source/DuckParty/DuckActor.h b/source/DuckParty/DuckActor.h
index eb92d3c..9ddf651 100644
--- a/source/DuckParty/DuckActor.h
+++ b/source/DuckParty/DuckActor.h
@@ -1,6 +1,7 @@
#pragma once
#include <chrono>
#include <caf/typed_event_based_actor.hpp>
+#include <caf/type_id.hpp>
#include "CustomMessages.h"

#include "Duck.h"
@@ -27,7 +28,7 @@ class DuckState {
return {
[this](do_duck_behavior) {
self_->delayed_send(self_, std::chrono::milliseconds(milliseconds_), do_duck_behavior_v);
-               std::chrono::time_point<std::chrono::system_clock> quackTime = std::chrono::system_clock::now();
+               auto quackTime = caf::make_timestamp();
std::string duck_display = duck_->GetFlyBehavior() + " " + duck_->GetNoiseBehavior();
self_->send(display_actor_, display_behavior_v, quackTime, duck_display);
}
diff --git a/source/DuckParty/main.cpp b/source/DuckParty/main.cpp
index 1a10d73..3f199c0 100644
--- a/source/DuckParty/main.cpp
+++ b/source/DuckParty/main.cpp
@@ -24,7 +24,7 @@ void caf_main(caf::actor_system& sys) {
DuckActor duck_actor3 = sys.spawn<DuckImpl>(move(duck3), 1500, display_actor);

caf::scoped_actor self(sys);
-   self->send(display_actor, display_behavior_v, std::chrono::system_clock::now(), "Let's get this party started!");
+   self->send(display_actor, display_behavior_v, caf::make_timestamp(), "Let's get this party started!");
}

CAF_MAIN(caf::id_block::duck_msg_types)

我没有运行任何二进制文件,但至少它是用最近的Visual Studio(社区版(在Windows 10上为我编译的。

不幸的是,CAF中的static_assert不会生成哪种类型未通过检查。但是,在调用send以快速找到有问题的类型之前,可以使用static_assert(caf::has_type_id_v<T>)逐个检查您的类型。

希望这能帮助你推进你的项目。🙂

最新更新