gpt4 book ai didi

c++ - 如果 iostream 对象不可复制,为什么下面的代码是合法的?

转载 作者:行者123 更新时间:2023-12-02 01:10:19 24 4
gpt4 key购买 nike

我一直在读《C++ Primer》,在第 8 章我们讨论了 I/O。据说I/O对象不能被复制或分配。如果是这样,那么为什么下面的代码会编译并运行?

std::ifstream get_lines(const std::string &fname, std::vector<std::string> &v)
{
std::ifstream file(fname);
if (!file) {
std::cerr << "Error opening file: " << fname << std::endl;
return file;
}

std::string buf;
while (std::getline(file, buf))
v.push_back(buf);

return file;
}

int main()
{
std::vector<std::string> v;
auto f = get_lines("test.txt", v);
f.close();

return 0;
}

返回的结果不是会创建一个 file 的拷贝,随后用于初始化 f 吗?

最佳答案

参见this page 。当你说

return file;

file 是一个“id-表达式”(即它是某个变量的名称)。这些在 return 下有特殊处理:

automatic move from local variables and parameters

If expression is a (possibly parenthesized) id-expression that names a variable ... then overload resolution to select the constructor to use for initialization of the returned value ... is performed twice:

  • first as if expression were an rvalue expression (thus it may select the move constructor), ...
  • then overload resolution is performed as usual, with expression considered as an lvalue (so it may select the copy constructor).

您无法复制 ifstream,这是事实,但您可以移动它。因此,编译器本质上会为您插入一个隐式的 std::move :

return std::move(file);

它允许调用ifstream的移动构造函数,即使复制构造函数已被删除。 “移动”意味着istream“拥有”的任何资源都会转移到新对象。移动构造函数从源对象中获取这些资源的所有权(从而修改它),同时将其交给新对象。对比复制构造函数,我们通常认为它不应该修改源代码,因此不能夺走其所有权。这使得复制构造函数对于 istream 来说不安全,因为这意味着两个对象试图管理一个外部资源,并且可能会相互混淆。移动构造函数不受合约约束,不会影响源对象,因此可以确保资源仅由一个对象拥有。

关于c++ - 如果 iostream 对象不可复制,为什么下面的代码是合法的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59762030/

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