gpt4 book ai didi

c++ - 从 const rvalue move

转载 作者:行者123 更新时间:2023-12-05 04:46:05 25 4
gpt4 key购买 nike

我遇到了一些代码,这些代码在通过 lambda 传递的函数参数中使用了对 std::function 的 const 右值引用。令人困惑的部分是它随后对该传入的参数进行了 std::move 调用。像这样:

using CallbackFn = std::function<void()>;
using AnotherCbFn = std::function<void(int)>;

void bar(AnotherCbFn&& cb) {
// doSomething();
}

void foo(CallbackFn const&& cb) {
// Some code
bar([ x = std::move(cb) /* <-- What's this? */](int value){
x();
});
}

void baz() {
foo([](){
// doSomethingMore();
});
}

传入 const 值引用然后对其调用 std::move 的目的是什么?所以我尝试了一个更简单的代码片段来查看在这种情况下会发生什么

#include <utility>
#include <string>
#include <cstdio>
#include <type_traits>

struct Foo {
Foo() = default;

Foo(Foo&& o) {
str = std::move(o.str); // calls the move assignment operator
std::printf("Other [%s], This [%s]\n", o.str.data(), str.data());
}

Foo(Foo const&& o) {
str = std::move(o.str); // calls the copy assignment operator
std::printf("Other [%s], This [%s]\n", o.str.data(), str.data());
}

private:
std::string str = "foo";
};

template <typename T>
void f(T&& x) {
if constexpr(std::is_const_v<T>) {
std::printf("Const rvalue\n");
auto temp = std::move(x);
} else {
std::printf("non-const rvalue\n");
auto temp = std::move(x);
}
}

Foo const getConstRvalue() {
return Foo();
}

Foo getNonConstRvalue() {
return Foo();
}

int main() {
f(getConstRvalue());
f(getNonConstRvalue());
}

产生了输出:

Const rvalue
Other [foo], This [foo]
non-const rvalue
Other [], This [foo]

检查 godbolt( here ) 的程序集确认发生了什么。 Foo(const&&) 调用 std::stringcopy-assignment 运算符:

call std::__cxx11::basic_string<char, std::char_traits,std::allocator >::operator=(std::__cxx11::basic_string<char,std::char_traits, std::allocator > const&)

同时 Foo(Foo&&) 调用 std::string move 赋值运算符:

call std::__cxx11::basic_string<char, std::char_traits,std::allocator >::operator=(std::__cxx11::basic_string<char,std::char_traits, std::allocator >&&)

认为(请纠正我!)const-lvalue 函数参数也可以绑定(bind)到const 右值参数(连同非const 右值, const 左值和非 const 左值),这就是为什么在 Foo(const&&) 的情况下有一个拷贝,因为 std::string 的 const-rvalue 可以' t 绑定(bind)到 move 赋值运算符中的非常量右值。

那么,传递 const 右值引用然后调用 std::move 的目的是什么,因为调用 std::move 通常意味着该值不应该在那之后使用,在这种情况下,实际上涉及一个拷贝而不是所需的 move 语义?是否有某种微妙的语言机制在起作用?

最佳答案

std::move 什么都不 move ,它只是将左值(对右值 cb 的引用)重新解释为您忘记显示的某些 bar 函数所期望的右值你的代码片段。

我怀疑它看起来像:

void bar(CallbackFn const&& cb) {
...
}

关于c++ - 从 const rvalue move ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68945503/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com