gpt4 book ai didi

C++11,返回 vector 函数风格的 move 语义

转载 作者:太空狗 更新时间:2023-10-29 23:49:40 25 4
gpt4 key购买 nike

我正在创建一个示例来尝试理解在使用 c++11 时如何优化 move 语义。

首先,我有以下两个函数,它们接受一些输入并返回输入的修改版本。

std::vector<float> abs(const std::vector<float> &v)
{
std::vector<float> abs_vec = v;

for (auto &val: abs_vec) {
auto i = &val - &abs_vec[0];
abs_vec[i] = std::abs(abs_vec[i]);
}

return abs_vec;
}

std::vector<float> normalize(const std::vector<float> &v)
{
std::vector<float> norm_vec = v;

auto max_val = std::max_element(std::begin(norm_vec), std::end(norm_vec));
auto min_val = std::min_element(std::begin(norm_vec), std::end(norm_vec));
auto norm_factor = *max_val;
auto min_check = std::abs(*min_val);

if (min_check > std::abs(norm_factor)) {
norm_factor = min_check;
}

for (auto &val: norm_vec) {
auto i = &val - &norm_vec[0];
norm_vec[i] = norm_vec[i] / norm_factor;
}

return norm_vec;
}

然后我用下面的代码测试函数:

int main()
{
std::vector<float> tmp{-1,2,-3,4,5};

printf("pointer before: %p\n", &tmp[0]);
tmp = normalize(tmp);
printf("pointer after normalize: %p\n", &tmp[0]);
tmp = abs(tmp);
printf("pointer after abs: %p\n", &tmp[0]);

};

从这里我得到输出:

pointer before: 0x156dc20
pointer after normalize: 0x156e050
pointer after abs: 0x156dc20

谁能解释一下这是怎么回事,为什么我在规范化后得到了一份拷贝,但在调用 abs 函数后却得到了与原始内存相同的内存位置?

有没有更好的方法来编写像这样的函数式风格的函数,从而产生更优化的代码?

最佳答案

我不确定为什么调用abs()后第一个元素的内存地址是一样的,但是有更好的写法。如果使用 std::transform(),代码会更简单,可在 algorithm header 中找到:

std::vector<float> abs(const std::vector<float> &v)
{
std::vector<float> abs_vec;

std::transform(v.begin(), v.end(), std::back_inserter(abs_vec),
[] (float val) {
return std::abs(val);
});

return abs_vec;
}

这将遍历 v 中的所有元素,并为每个元素调用 lambda 函数。该函数的返回值将被插入到 abs_vec 的末尾。

normalize() 末尾的循环也可以重写为使用 std::transform()。在这种情况下,可以捕获 norm_factor 变量,以便在 lambda 中使用它:

std::transform(v.begin(), v.end(), std::back_inserter(norm_vec),
[norm_factor] (float val) {
return val / norm_factor;
});

关于C++11,返回 vector 函数风格的 move 语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38266739/

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