无法理解为什么完美转发不起作用
Cannot understand why perfect forwarding is not working
我试图了解完美的转发是如何工作的,但我不明白为什么在下面的代码中调用复制构造函数
#include <utility>
#include <iostream>
using std::cout;
using std::endl;
class Something {
public:
Something() = default;
Something(__attribute__((unused)) const Something& other) {
cout << "Copy constructor called" << endl;
}
Something(__attribute__((unused)) Something&& other) {
cout << "Move constructor called" << endl;
}
void print() {
cout << "Something::print() called" << endl;
}
};
void function_1(Something&& one) {
cout << "version two called" << endl;
Something inner{one};
inner.print();
}
void function_1(const Something& one) {
Something inner(one);
inner.print();
}
template <typename... T>
void test_function(T&&... ts) {
function_1(std::forward<T>(ts)...);
}
int main() {
const Something some1 {Something()};
test_function(some1);
test_function(Something());
return 0;
}
这将产生以下输出
Copy constructor called
Something::print() called
version two called
Copy constructor called
Something::print() called
更改代码以在右值引用中包含std::move
有效,但我没想到需要它。 当引用是右值引用时,应该自动调用正确的构造函数,对吗? 解析了正确的引用,但调用了错误的构造函数。 任何帮助将不胜感激!
右值引用绑定到右值。 它本身不是一个右值,因为它有一个名字。
但是默认情况下,任何在使用点具有名称的东西都是左值,即使是右值引用也是如此。 你的代码可以使用Something&& one
三次,如果第一次隐式使用move
,你就会被搞砸。
相反,它是使用点的左值(默认情况下),并且绑定到右值。
当您想要发出信号时,不再需要其状态持续存在,请std::move
它。
完美的转发可用于写入您的两个function_1
,方法是在您想要从 blah 移动的点放置一个std::forward<Blah>(blah)
(如果它是一个右值引用)。
现在上面充满了谎言,因为有x值prvalues lvalues等 - 标准更复杂。 例如,在 return 语句中使用变量可以将命名值转换为右值。 但基本的经验法则值得了解:它有一个名称,它是一个左值(除非显式强制转换或过期)。
此代码将调用复制 ctor,而不是移动 ctor。
void function_1(Something&& one) {
cout << "version two called" << endl;
Something inner{one};
inner.print();
}
此代码调用移动 ctor。
void function_1(Something&& one) {
cout << "version two called" << endl;
Something inner{std::move(one)};
inner.print();
}
表达式 one
在技术上是一个 l 值。它指的是右值引用。但是要实际获得右值引用,您必须使用 std::move
.通常,任何有名称的东西都是 l 值。未命名的临时,例如您在main()
中的Something()
表达式:
test_function(Something());
可以是右值,并且可以在不使用std::move
的情况下调用移动。
- 将函数参数完美转发到函数指针:按值传递呢?
- C++20理念:要求表达和完美转发
- 我可以列表初始化 std::vector 并完美转发元素吗?
- 返回值的完美转发?
- 使用衰减与完美转发
- 可变参数模板:将整数参数完美转发到 lambda
- 完美转发C++重载和模板化函子及其参数
- 在完美转发中需要衰减
- C++完美转发:如何避免悬空引用
- 无法理解一段具有完美转发和省略号的C++代码
- 在编写包装现有函数并检查错误的模板函数时,如何使用完美转发?
- 完美转发可变参数模板模板
- 在完美转发函数中公开参数类型,避免代码重复
- 使用完美转发的模板转换构造函数
- 完美转发使用结构化绑定声明的变量
- 完美转发常量参数以进行持续评估
- 使用auto&&完美转发返回值
- 完美转发可变参数模板参数到成员函数
- 无需使用 ODR 即可实现完美转发
- 使用模板类完美转发