Asio 协程在使用右值参数时表现不佳?

2024-04-01

我可能做了一些明显错误的事情,但为什么会在 MSVC 上打印垃圾?

#include <sdkddkver.h>

#include <boost/asio.hpp>
#include <iostream>

namespace asio = boost::asio;

template <typename Str>
asio::awaitable<void> coro_task(Str&& str) {
  std::cout << "coro_task: " << str << std::endl;
  co_await asio::this_coro::executor;
}

template <typename Str>
void sync_task(Str&& str) {
  std::cout << "sync_task: " << str << std::endl;
}

int main() {
  asio::io_context ioc;
  asio::co_spawn(ioc.get_executor(), coro_task("hello world"), asio::detached);
  asio::post(ioc.get_executor(), [] { sync_task("hello world"); });

  ioc.run();
}

例如:

coro_task: ╕÷ⁿäg
sync_task: hello world

我不明白为什么会这样。一定Str将是静态生命周期char[12] &,所以我不明白为什么它会得到垃圾数据。

如果我将任何具有暂时生命周期的东西传递给coro_task (e.g. coro_task(std::string{"hello world"}))我没有得到输出(str是空的)。我猜想它是从某个地方搬来的,但不知道在哪里。

尝试为阻塞函数创建通用异步任务/协程包装器时遇到此问题:https://stackoverflow.com/a/75228866/3554391 https://stackoverflow.com/a/75228866/3554391。这个问题代表了这个问题的一个最小例子。

该问题似乎没有发生与 godbolt 上的 gcc 一起使用 https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:%271%27,fontScale:14,fontUsePx:%270%27,j:1,lang:c%2B%2B,selection:(endColumn:2,endLineNumber:23,positionColumn:2,positionLineNumber:23,selectionStartColumn:2,selectionStartLineNumber:23,startColumn:2,startLineNumber:23),source:%27%23include+%3Cboost/asio.hpp%3E%0A%23include+%3Ciostream%3E%0A%0Anamespace+asio+%3D+boost::asio%3B%0A%0Atemplate+%3Ctypename+Str%3E%0Aasio::awaitable%3Cvoid%3E+coro_task(Str%26%26+str)+%7B%0A++std::cout+%3C%3C+%22coro_task:+%22+%3C%3C+str+%3C%3C+std::endl%3B%0A++co_await+asio::this_coro::executor%3B%0A%7D%0A%0Atemplate+%3Ctypename+Str%3E%0Avoid+sync_task(Str%26%26+str)+%7B%0A++std::cout+%3C%3C+%22sync_task:+%22+%3C%3C+str+%3C%3C+std::endl%3B%0A%7D%0A%0Aint+main()+%7B%0A++asio::io_context+ioc%3B%0A++asio::co_spawn(ioc.get_executor(),+coro_task(%22hello+world%22),+asio::detached)%3B%0A++asio::post(ioc.get_executor(),+%5B%5D+%7B+sync_task(%22hello+world%22)%3B+%7D)%3B%0A%0A++ioc.run()%3B%0A%7D%27),l:%275%27,n:%270%27,o:%27C%2B%2B+source+%231%27,t:%270%27)),k:59.375,l:%274%27,n:%270%27,o:%27%27,s:0,t:%270%27),(g:!((g:!((h:compiler,i:(compiler:g131,deviceViewOpen:%271%27,filters:(b:%270%27,binary:%271%27,binaryObject:%271%27,commentOnly:%270%27,debugCalls:%271%27,demangle:%270%27,directives:%270%27,execute:%270%27,intel:%270%27,libraryCode:%270%27,trim:%271%27),flagsViewOpen:%271%27,fontScale:14,fontUsePx:%270%27,j:1,lang:c%2B%2B,libs:!((name:boost,ver:%27182%27)),options:%27-std%3Dc%2B%2B20+-Wall+-Wextra+-pedantic+-Werror+-lpthread%27,overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:%275%27,n:%270%27,o:%27+x86-64+gcc+13.1+(Editor+%231)%27,t:%270%27)),header:(),l:%274%27,m:70.82658022690438,n:%270%27,o:%27%27,s:0,t:%270%27),(g:!((h:output,i:(compilerName:%27x86-64+gcc+13.1%27,editorid:1,fontScale:14,fontUsePx:%270%27,j:1,wrap:%271%27),l:%275%27,n:%270%27,o:%27Output+of+x86-64+gcc+13.1+(Compiler+%231)%27,t:%270%27)),header:(),l:%274%27,m:29.17341977309562,n:%270%27,o:%27%27,s:0,t:%270%27)),k:40.625,l:%273%27,n:%270%27,o:%27%27,t:%270%27)),l:%272%27,n:%270%27,o:%27%27,t:%270%27)),version:4 or 伴随着铿锵声 https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:%271%27,fontScale:14,fontUsePx:%270%27,j:1,lang:c%2B%2B,selection:(endColumn:2,endLineNumber:23,positionColumn:2,positionLineNumber:23,selectionStartColumn:2,selectionStartLineNumber:23,startColumn:2,startLineNumber:23),source:%27%23include+%3Cboost/asio.hpp%3E%0A%23include+%3Ciostream%3E%0A%0Anamespace+asio+%3D+boost::asio%3B%0A%0Atemplate+%3Ctypename+Str%3E%0Aasio::awaitable%3Cvoid%3E+coro_task(Str%26%26+str)+%7B%0A++std::cout+%3C%3C+%22coro_task:+%22+%3C%3C+str+%3C%3C+std::endl%3B%0A++co_await+asio::this_coro::executor%3B%0A%7D%0A%0Atemplate+%3Ctypename+Str%3E%0Avoid+sync_task(Str%26%26+str)+%7B%0A++std::cout+%3C%3C+%22sync_task:+%22+%3C%3C+str+%3C%3C+std::endl%3B%0A%7D%0A%0Aint+main()+%7B%0A++asio::io_context+ioc%3B%0A++asio::co_spawn(ioc.get_executor(),+coro_task(%22hello+world%22),+asio::detached)%3B%0A++asio::post(ioc.get_executor(),+%5B%5D+%7B+sync_task(%22hello+world%22)%3B+%7D)%3B%0A%0A++ioc.run()%3B%0A%7D%27),l:%275%27,n:%270%27,o:%27C%2B%2B+source+%231%27,t:%270%27)),k:59.375,l:%274%27,n:%270%27,o:%27%27,s:0,t:%270%27),(g:!((g:!((h:compiler,i:(compiler:clang1600,deviceViewOpen:%271%27,filters:(b:%270%27,binary:%271%27,binaryObject:%271%27,commentOnly:%270%27,debugCalls:%271%27,demangle:%270%27,directives:%270%27,execute:%270%27,intel:%270%27,libraryCode:%270%27,trim:%271%27),flagsViewOpen:%271%27,fontScale:14,fontUsePx:%270%27,j:1,lang:c%2B%2B,libs:!((name:boost,ver:%27182%27)),options:%27-std%3Dc%2B%2B20+-Wall+-Wextra+-pedantic+-Werror+-pthread%27,overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:%275%27,n:%270%27,o:%27+x86-64+clang+16.0.0+(Editor+%231)%27,t:%270%27)),header:(),l:%274%27,m:70.82658022690438,n:%270%27,o:%27%27,s:0,t:%270%27),(g:!((h:output,i:(compilerName:%27x86-64+gcc+13.1%27,editorid:1,fontScale:14,fontUsePx:%270%27,j:1,wrap:%271%27),l:%275%27,n:%270%27,o:%27Output+of+x86-64+clang+16.0.0+(Compiler+%231)%27,t:%270%27)),header:(),l:%274%27,m:29.17341977309562,n:%270%27,o:%27%27,s:0,t:%270%27)),k:40.625,l:%273%27,n:%270%27,o:%27%27,t:%270%27)),l:%272%27,n:%270%27,o:%27%27,t:%270%27)),version:4.

我正在使用 Visual Studio 17.5.5 和 asio 1.25.0。


从广义上讲,协程不应该通过引用获取参数。不同于,例如,std::async,C++ 的协程系统尝试将引用参数转换为本地副本的努力为零。

这解释了当你给它类似的对象时它的行为std::string。要理解它在直接处理字符串文字时的行为......事情变得复杂。

在普通函数中,参数是由调用函数有效创建的。由于协程must它比其函数调用引用的上下文更长寿,它有一种机制可以将参数“复制”到与协程状态关联的存储中。如果参数是值参数,则它将由原始参数的 xvalue 表达式初始化(​​因此可以从中移动)。但是,如果这些参数是参考参数,则“复制”将also可以作为同类型的参考。

这就是我们遇到一些问题的地方。用于转发字符串文字引用的模板参数推导会生成对字符串数组的引用。但这是对暂时的数组,通过使用字符串文字作为模板函数的参数来体现。如果该函数采取了char const*,那么所讨论的数组将是指向静态内存的指针。但相反,您拥有的是对临时对象的引用,该引用由函数的调用者拥有。

因此将在协程暂停的那一刻到期。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Asio 协程在使用右值参数时表现不佳? 的相关文章

  • Visual Studios 2015 中的“恢复 NuGet 包”没有执行任何操作

    我将解决方案从 SVN 拉入 Visual Studios 2015 代码中的一些 使用 引用出现错误 因此我尝试在右键单击 解决方案 中的解决方案时运行 恢复 NuGet 包 选项探索者 这没有任何作用 我必须手动进入 nuget 管理器
  • 更新 Azure Blob 上的 LastModified

    我正在移植代码以使用 C 中的 Azure 存储 SDK 传统上 我称其为更新修改文件的上次写入 修改时间 File SetLastWriteTimeUtc fileName lastWriteTimeUtc 要更新 blob 的上次修改时
  • 如何通过覆盖 MSBuild 目标来防止外语资源生成?

    我正在致力于减少大型 C ASP NET 解决方案的编译时间 我们的解决方案使用通常的 resx 文件方法翻译成大约十几种外语 这些资源文件的解析和编译极大地减慢了我们的编译时间 并且是日常的挫败感 我知道可以创建自定义资源提供程序并摆脱
  • C# 异步任务比同步慢

    你知道为什么同步斐波那契方法比异步 等待更快并且比异步任务更快吗 我在每个项目方法上都使用了异步 所以主要是这是一个非常糟糕的方法 Code static int FibonacciSync int number if number 0 r
  • 信号与信号2

    我的应用程序可能会受益于使用 boost 的信号库之一而不是本土解决方案 该应用程序是多线程的 但执行信号处理的部分是单线程的 如果多线程不是问题 是否有任何理由更喜欢 Boost Signals2 而不是 Boost Signal Boo
  • 头文件中实现的函数的静态与内联

    我想到的方式inline在 C 中用于链接 作用域 我把它放在同一个篮子里extern and static对于全局对象 通常 对于在头文件中实现的函数 我的首选解决方案是将其设为静态 In Foo h static void foo Do
  • 如何通过 libwebsocket 发送异步数据?

    我正在将 Warmcat 的 libwebsocket C 库用于小型 Websocket 服务器 我已经启动并运行了这些示例 并且可以发送数据以响应从 websocket 接收数据 例如回显发送的反向字节 但是 我无法弄清楚如何在不使用
  • C# 中 PKCS11Interop 库的线程安全使用 [已关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在使用 PKCS11Interop 在 HSM 内执行密钥管理操作 我使用的 HSM 是 Thales PCI Express 下面是
  • 无法将参数从 `const char *` 转换为 `char *`

    鉴于此代码 void group build int size std string ips Build the LL after receiving the member list from bootstrap head new memb
  • 从内存流播放视频文件

    只是好奇看看这是否可能 我有一个 Windows 应用程序 它从我的电脑上的 avi 文件读取所有字节 然后将其存储在 byte 中 现在我的内存中有 avi 文件 我想直接从内存将其加载到某种视频播放器控件中 我尝试过使用 wmplaye
  • 为什么像 BindingList 或 ObservableCollection 这样的类不是线程安全的?

    我一次又一次发现自己必须编写 BindingList 和 ObservableCollection 的线程安全版本 因为当绑定到 UI 时 这些控件无法从多个线程更改 我想理解的是why情况就是这样 这是设计错误还是故意的 问题是设计一个线
  • std::make_pair 与浮点数组(float2,无符号整数)

    我有一个用 float2 unsigned int 对模板化的向量 例如 std vector
  • 检查两个函数或成员函数指针的签名是否相等

    我编写了一些代码来检查自由函数的签名是否等于成员函数的签名等 它比较提取的返回类型和函数参数 include
  • ASP.NET MVC 动作过滤器

    有谁知道即使在 CATCH 块中 ActionFilterAttribute 类的 OnResultExecuted 方法是否也会执行 ie CookiesActions public ActionResult Login Usuarios
  • 展开 std::reference_wrapper 的成本

    Given include
  • 检查一个数是否是完全平方数?

    我认为以下代码存在精度问题 bool isPerfectSquare long long n long long squareRootN long long sqrt n 0 5 return squareRootN squareRootN
  • 强制函数调用的顺序?

    假设我有一个抽象基类 并且我想要一个必须由派生类实现的纯虚方法 但我想确保派生方法以特定顺序调用函数 我可以做什么来强制执行它 I E base class virtual void doABC 0 virtual void A 0 vir
  • Asp.Net Core 中的 SSL 不起作用

    我从 Visual Studio 创建了一个简单的 Web 应用程序Web Application Net Core 具有个人用户帐户授权的模板 然后 我启用了 SSLProject gt MyProject Properties 将带有
  • 在 C# 中使用自定义千位分隔符

    在显示字符串时 我尝试不使用 字符作为千位分隔符 而是使用空格 我想我需要定义一种自定义文化 但我似乎做得不对 有什么指点吗 例如 将 1000000 显示为 1 000 000 而不是 1 000 000 no String Replac
  • 如何根据当前日期时间发现财政年度?

    我需要基于当前或今天的日期时间的财政年度 假设我们认为今天的日期是10 April 2011 那么我需要输出为Financial Year 2012在某些情况下 我需要以短格式显示相同的输出FY12 我想以两种方式显示 在我们的要求中 考虑

随机推荐

  • Tkinter Windows 按键事件

    Tkinter 中 Windows 键的事件是什么 我使用的是 Linux 但我想要 Linux 和 Windows 的答案 如果 Mac 有类似的密钥 请随时告诉我它的绑定 我想左右 windows 键有不同的事件 Windows 键似乎
  • 将用户的时区与网站办公地点的时区进行比较

    我正在开发一个项目 我需要在联系人区域向网站访问者显示一条消息 例如 联系电话 91 99 3241 5285 You can call us now 该消息在上面一行中突出显示 现在我的问题是 如何将用户的时区与公司办公室的工作时间进行比
  • 从 Fluent Nhibernate 获取表名

    在流畅的 nhibernate 中设置映射后 有没有办法从类类型中获取实体的表名 我读过常规的 nhiberante 你可以做类似的事情cfg GetClassMapping typeof Employee 我想做这样的事情来检索数据库表名
  • 有没有办法在我的代码中使用 Typescript.Collections.HashTable ?

    我在 Typescript 编译器的代码中看到了 HashTable 的实现 在文件 src compiler core hashTable ts 中 你知道有没有办法可以直接在我的 Typescript 项目中使用它 您可以通过定义接口来
  • 将向量数组作为函数参数传递(值不会改变)

    我在一类中有一组向量 class MeasurementData private std vector
  • laravel 5 根据路由返回 HTML 或 JSON

    我想显示不同的输出 JSON 或 HTML 我无法使用 Request ajax 功能 因为我只是收到正常请求 JSON 响应不是基于 XHR 请求 是否有可能区分不同路线的输出 例如 检查控制器是否由前缀为 mob 的路由调用 然后根据该
  • 检测从 C# 应用程序最小化的所有窗口

    如何检测从 C 应用程序最小化的所有窗口 其他应用程序 使用这里的示例http pinvoke net default aspx user32 EnumDesktopWindows http pinvoke net default aspx
  • 单独运行时单个规范通过,但运行所有规范时失败

    我的 foo controller spec rb 中有 30 个规范 当我使用规范运行整个文件时 我得到 4 个失败和 2 个待处理 当我单独运行 4 个失败的规范时 其中 3 个仍然失败 但其中一个通过了 起初我认为这是一个数据库问题
  • C++ New 与 Malloc 用于对象的动态内存数组

    我有一个 Bullet 类 它的构造需要几个参数 但是 我使用动态内存阵列来存储它们 我正在使用 C 所以我想通过使用 new 运算符来分配内存来符合它的标准 问题是当我分配数组时 new 运算符要求构造函数参数 而当时我没有 我可以使用
  • 从表中删除*不起作用[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在尝试删除all rows从表中但它不起作用 当我做echo mydb gt error 它给了我以下内容 You have an e
  • Node-PerfectAPI vs Restify.js vs ExpressJS vs Node-APIServer [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我是 ExpressJS 的新手 我想为我的服务创建 API 该服务将直接由其他服务器使用 并且一部分也由移动应用程序 浏览器使用 我刚刚发现了
  • Dagger 和 mvp - 演示者是否应该使用 dagger 进行注入

    我开始认为在mvp中 匕首不应该在presenter中使用 构造 dagger 的常用方法是使用全局组件并具有用于确定图形范围的子组件 该全局组件通常在创建 appmodule java 类时将 applicationContext 作为参
  • 如何在 Scala 中模拟“一次分配”变量?

    这是一个后续问题我之前的初始化变量问题 https stackoverflow com questions 4400926 can i define method private fields in scala 假设我们正在处理这样的上下文
  • Android Profiler 未出现在 Android Studio 中

    我想分析我的设备中的内存消耗 但我没有找到Android 分析器Android Studio 中的选项卡如下所示 请问谁能帮我显示这个选项卡 如果你看一下顶部菜单 你会看到个人资料图标单击它 它将启动您的应用程序并附加配置文件 请参阅下面的
  • Spark - Scala - saveAsHadoopFile 抛出错误

    我想解决该问题 但无法进一步进行 有人可以帮忙吗 import org apache hadoop mapred lib MultipleTextOutputFormat class KeyBasedOutput T gt Null V l
  • iOS 8 SpriteKit 在从块/操作中添加或删除子项时崩溃

    从 iOS8 开始 我的游戏突然开始崩溃 经过一番调试 我发现游戏在以下两个地方崩溃 sparkNode runAction SKAction sequence Some actions and finally SKAction remov
  • 在 Ruby 中读取文件的第一行

    我想读书only以最快 最简单 最惯用的方式使用 Ruby 来编写文件的第一行 最好的方法是什么 具体来说 我想从我最新的 Capistrano 部署的 Rails 目录中的 REVISION 文件中读取 git commit UUID 然
  • C# 字符串到长指针

    我正在使用 C 中的应用程序 需要向 C 应用程序发送消息 我导入了 DllImport user32 dll public static extern IntPtr SendMessage int hWnd handle to desti
  • jar 文件损坏

    我使用 eclipse 在 Windows 7 中创建了一个 jar 文件 当我尝试打开 jar 文件时 它显示 jar 文件无效或损坏 谁能告诉我为什么 jar 文件无效 当您在 Windows 资源管理器中双击 JAR 文件时会发生这种
  • Asio 协程在使用右值参数时表现不佳?

    我可能做了一些明显错误的事情 但为什么会在 MSVC 上打印垃圾 include