gpt4 book ai didi

C++: move/转发/右值委托(delegate)恶作剧

转载 作者:行者123 更新时间:2023-11-28 02:21:43 26 4
gpt4 key购买 nike

<分区>

尝试运行这个测试程序:

#include <iostream>

class A {
public:
A() { std::cout << "empty constructor" << std::endl; }
A(const A &a) { std::cout << "copy constructor" << std::endl; }
A(A &&a) { std::cout << "move constructor" << std::endl; }
~A() { std::cout << "destructor" << std::endl; }
A &operator=(const A &o) { std::cout << "copy assignment" << std::endl; return *this; }
A &operator=(A &&o) { std::cout << "move assignment" << std::endl; return *this; }
};

A outside;

template <typename U>
void bar(U &&a) {
outside = std::forward<U>(a);
}

void foo(A &&a) {
bar(a);
}

int main(int argc, char *argv[]) {
foo(A());
return 0;
}

在我的编译器上,我认为是 GCC 4.4.1,输出是:

empty constructor
empty constructor
copy assignment // what??
destructor
destructor

在我看来,第三行很奇怪。为什么 outsidebar 中复制 a 而不是 move 它?换句话说,为什么 foo 使用 bar(A &a) 实例化 bar 而不是 bar(A &&a)?

我应该提一下,通过将 foo 更改为

可以轻松解决此问题
template <typename U>
void foo(U &&a) {
bar(std::forward<U>(a));
}

于是使用了 move 赋值运算符。

在我的代码中,我有很多委托(delegate)方法,我不愿意将它们全部放在一个 .h 文件中并为它们制作模板。是否有另一种方式告诉编译器或让它理解 afoo 中用作右值?

编辑:一些人指出了这一变化:

void foo(U &&a) {
bar(std::move(a));
}

我太慢了,无法表明我希望 foo 能够接受两者:

int main(int argc, char *argv[]) {
foo(A());
return 0;
}

int main(int argc, char *argv[]) {
A a;
foo(a);
return 0;
}

在第二种情况下,建议的代码将错误地窃取 amain 中应该用作引用的资源。

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