在 C++ 中编写 `return {data, uninitialized_copy(b, e, data)};` 是未定义行为吗

问题描述

嗨,我正在阅读一个示例,说明如何在不使用其中一本书中的模板的情况下定义我们自己的类向量。现在这里一个函数定义如下:

pair<string *,string*> StrVec::alloc_n_copy(const string *b,const string *e)
{
   auto data = alloc.allocate(e - b);
   return {data,uninitialized_copy(b,e,data)};

}

现在我的问题是上面的 return 语句是未定义的行为吗?例如,我知道以下语句是未定义的行为:

std::cout<< i << ++i<<std::endl;

既然这个示例语句是未定义的,那么 return 语句不应该也是未定义的吗?因为它也改变了变量 data 的值。

解决方法

你说得对

std::cout<< i << ++i<<std::endl;

is 是 UB(在 C++17 之前),因为 i 在序列点之间被读取修改。

不过

return {data,uninitialized_copy(b,e,data)};

不会改变data。它只更改 data 指向的元素。

,

std::cout << i << ++i << std::endl; 的问题在于 i 在同一个表达式中使用了两次,并且一次被修改。围绕这个话题有很多问题和答案,所以我只是参考它们。

在你的代码中

return {data,data)};

data 未修改。在调用 data 之前获取 uninitialized_copy 的值,还是在将其副本传递给 {{1} 后返回 data 的值都没有关系}.

也许这就是你错过的细节。 unitialized_copy 是:

std::unitialized_copy

即所有参数均按值获取。

类似于

template< class InputIt,class ForwardIt >
ForwardIt uninitialized_copy( InputIt first,InputIt last,ForwardIt d_first );

没有错。