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

Is it Undefined Behavior to write `return {data, uninitialized_copy(b, e, data)};` in C++

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

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, uninitialized_copy(b, e, data)};

data 未修改。在调用 uninitialized_copy 之前获取 data 的值,或者在将 data 的副本传递给之后 return 的值都没有关系unitialized_copy.

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

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

即所有参数都取值

它类似于

 int foo(int x) { return 2*x; }

 int bar(int y)  { return y + foo(y); }

没有错。