c++ - 避免通过 std::transform 进行复制构造
问题描述
我用一个 lambda 调用 std::transform ,它通过引用获取并返回对向量元素的引用。但是,根据我的程序输出,调用了复制构造函数并且对象不一样。
代码:
#include <algorithm>
#include <iostream>
#include <vector>
class Math
{
private:
int val_ = 5;
public:
Math(const Math& m) {
std::cout << "Copy constructor, our address: " << this << ", his address: " << &m << std::endl;
}
Math(int val) : val_(val) {
std::cout << "Object constructed with " << val << std::endl;
}
};
int main()
{
std::vector<Math> v_math = { { 5 }, { 10 } };
std::transform(
begin(v_math),
end(v_math),
begin(v_math),
[](const Math& m)-> const Math& {
return m;
});
}
输出(神箭):
Object constructed with 5
Object constructed with 10
Copy constructor, our address: 0x23d7ec0, his address: 0x7fff9dc499a8
Copy constructor, our address: 0x23d7ec4, his address: 0x7fff9dc499ac
所以我现在还不清楚三件事:
- 为什么对象不同?他们不应该是一样的吗?
- 为什么一个对象的地址比另一个大?这是因为复制到的对象保留在具有偏移指针的堆栈上吗?
- 我怎样才能避免复制构造(实际上我只是“误用” std::transform 以声明性方式在每个 std::vector 元素上调用 lambda)?
解决方案
副本与您使用std::transform
. 它们在您构造 时发生v_math
std::vector
,因为您使用的是std::initializer_list
构造函数,该构造函数在构造过程中强制复制。
在您的std::transform
通话中,operator=(const Math&)
被调用,将您的代码更改为以下内容以查看此内容。
class Math
{
private:
int val_ = 5;
public:
Math(const Math& m) {
std::cout << "Copy constructor, our address: " << this << ", his address: " << &m << std::endl;
}
Math(int val) : val_(val) {
std::cout << "Object constructed with " << val << std::endl;
}
Math& operator=(const Math& other) {
val_ = other.val_;
std::cout << "Operator=(const Math&) called!\n";
return *this;
}
};
int main()
{
std::vector<Math> v_math = { { 5 }, { 10 } };
std::cout << "After constructing v_math!\n";
std::transform(
begin(v_math),
end(v_math),
begin(v_math),
[](const Math& m)-> const Math& {
return m;
});
std::cout << "After std::transform call!\n";
}
推荐阅读
- javascript - React Native apk 在物理设备上显示空白,但在 Android 模拟器上不显示
- python - 为什么python在使用torchtext和pytorch时不能导入词汇?
- vba - 如何通过代码在Excel插入函数对话框中设置类别
- node.js - Istio 中的 Jaeger 跟踪的跨度不超过 2 个(nodejs 中的服务)
- c# - 从 LINQ 查询返回命名元组
- python - 根据最后一列对相关矩阵进行排序
- html - 尝试包含密码眼睛时的自定义输入字段边框行为
- javascript - Vue.Js 渲染列表到一定限度
- c# - 即使不应该运行代码行
- arm - STM32中断引脚奇怪行为