- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我遇到了一些代码,这些代码在通过 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::string
的copy-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/
They say Rvalues 的成员也是 Rvalues - 这很有意义。所以这要么是 VC++ 特有的错误,要么是我对右值理解的错误。 拿这个玩具代码: #include #include
(我搜索了[c++]“c++中的函数式编程”一书,只给出了4个不相关的结果。) 我正在阅读来自 Ivan Čukić 的 C++ 函数式编程 , 在第 118 页有一句话我不确定我是否理解。该节是关于
以下代码无法编译。 Clang 给出此错误消息:候选函数不可行:第一个参数没有从“A”到“A &&”的已知转换 这就好像 f() 中的 a 是一个左值。 struct A{}; void g(A&&
假设我有以下对象 class foo { foo() {..} //Constructor foo(const foo& f) {..} //Copy
我最近一直在玩 Rvalue 引用,但遇到了一个奇怪的问题。让我们定义一些名为 Foo 的简单类,其中包含一个 vector : class Foo { public: Foo(std::ve
RValue 引用的堆栈大小是多少? 例如在这样的情况下: struct A { /* ... */ }; A getA() { A temp; return
RValue 引用的堆栈大小是多少? 例如在这样的情况下: struct A { /* ... */ }; A getA() { A temp; return
现在我有一个只有一个构造函数的类 ShaderProgram(std::initializer_list> shaders); 我正在使用引用包装器,因为我没有引用的 initializer_list
我一直在努力理解移动构造函数场景背后发生的事情,但我的脑海中缺少了一些东西。 struct A { int s; A() : s(10) {} A(const A&
我有一个可变模板函数 template inline void ReadStream::decode(ARGS&...args) { internalDecode(args...); } tem
RValues 是不可操作的内存区域,因此像整数这样的文字被认为是 RValues。 常量构成 RValues 吗? const int x = 0; 至少可操作一次。 现在,编译器创建的临时对象也是
“*this 的右值引用”最典型的用例是什么?标准也将其称为成员函数的引用限定符? 顺便说一下,关于这个语言特性有一个非常好的解释 here 。 最佳答案 调用时,每个成员函数都有一个 *this 引
我有一个带有值的 vector : obj={1.0,2.0,3.0, 4.0,5.0,6.0 ,7.0,8.0,9.0,10.0} 假设,在数学上 obj 被划分为三个子 vector : obj=
考虑以下 C++ 代码 template void f (const int x, const int y, Args&&... args) { // Do something } 据我了解,这
考虑以下代码: int three() { return 3; } template class Foo { private: T* ptr; public: void ba
在 clang 的 C++11 status page 中遇到了一个名为“*this 的右值引用”的提议. 我已经阅读了很多关于右值引用的内容并理解了它们,但我认为我对此一无所知。我在网络上也找不到太
我遇到了下面的代码,但我在谷歌上找不到为什么下面的语句是有效的 C++: Base&& b = Derived(); 请解释或给出引用 这是一个示例代码: #include using namesp
在 clang 的 C++11 status page 中遇到了一个名为“*this 的右值引用”的提议. 我已经阅读了很多关于右值引用的内容并理解了它们,但我认为我对此一无所知。我在网络上也找不到太
我遇到了 RValue 不允许隐式转换的问题。我的问题是什么实现更好地“绕过”这个限制? 下面是说明问题的示例代码: template class ITestClass { public: vir
我想知道这怎么可能? template void Test(T&& arg) { arg = 14; } int a = 23; Test(a); 我的问题是函数 Test 需要一个右值类型的
我是一名优秀的程序员,十分优秀!