【问题标题】:Moving std::string into capture将 std::string 移动到捕获中
【发布时间】:2020-09-09 07:57:03
【问题描述】:

考虑以下示例,该示例采用 msg 并异步发布。

    void sendMessage(std::string msg) {
        runAsync<void>([msg = std::move(msg)] {
            onPostMessage(cookie, msg.c_str());
        });
    };

以下会更快吗?

void sendMessage(std::string&& msg) {

呼叫站点的最佳选择是什么?

    auto msg = ...
    postMessage(msg);

    auto msg = ...
    postMessage(std::move(msg));

请注意,调用后不再需要msg

编译器会在调用后自动检测到我不再使用msg 并“移动”它吗?

【问题讨论】:

  • 编辑:啊,你只用 C++14 标记,没关系... 原始评论:我认为 std::string_view 会比对 std::string 的 r 值引用更好。但除此之外,我认为它们在速度上应该是相等的(字符串只有在按照 C++17 规则实际使用时才会实现)。然而,原始版本更好,因为它同时适用于左值和右值(更易于使用)。复制省略也可能会发生。
  • 重点是在调用站点,msg 发布后不需要,所以我试图找到最有效的方法将其传递到最终将其移动到捕获中...
  • 如果您仅限于 C++14,则编译器会有所不同,因为没有保证复制省略或移动省略。但即便如此,我还是会说使用 value 和 std::move 更好。或者,您可以尝试制作msg const,这也可能导致一些优化。但在 C++17 之前,标准无法保证...
  • 将其设为const std::string msg 会如何影响最终进入捕获阶段?
  • @user3612643 答案:是的,其次,不是。

标签: c++ c++11 c++14


【解决方案1】:

我会使用以下解决方案:

void sendMessage(std::string&& msg) {
    runAsync<void>([msg = std::move(msg)] {
        onPostMessage(cookie, msg.c_str());
    });
};

在调用站点:

auto msg = ...
sendMessage(std::exchange(msg, {}));

【讨论】:

  • 为什么要交换而不是移动?
  • @user3612643 在 std::move 之后,味精变得有效,但处于未指定状态。所以,为了避免在 sendMessage 之后无意中使用了变量,我更喜欢 std::exchange。请参阅(8)link
猜你喜欢
  • 1970-01-01
  • 2012-09-25
  • 1970-01-01
  • 1970-01-01
  • 2014-04-26
  • 1970-01-01
  • 1970-01-01
  • 2012-05-04
  • 2015-01-17
相关资源
最近更新 更多