C++ 按值返回ifstream编译
我注意到我能够按值从函数返回C++ 按值返回ifstream编译,c++,C++,我注意到我能够按值从函数返回std::ifstream,而编译器不会给我任何与已删除副本构造函数相关的错误。这不应该起作用,因为ifstreams不应该是可复制的,所以我认为它以某种方式内联了函数?有人对此有解释吗 我正在用苹果LLVM版本7.3.0(clang-703.0.31)运行MacOSX El Capitan 10.11.6++ ifstream enterFile(){ ifstream输入(“hello.txt”); 返回输入; } int main(){ ifstream f=e
std::ifstream
,而编译器不会给我任何与已删除副本构造函数相关的错误。这不应该起作用,因为ifstreams不应该是可复制的,所以我认为它以某种方式内联了函数?有人对此有解释吗
我正在用苹果LLVM版本7.3.0(clang-703.0.31)运行MacOSX El Capitan 10.11.6++
ifstream enterFile(){
ifstream输入(“hello.txt”);
返回输入;
}
int main(){
ifstream f=enterFile();
弦线;
while(getline(f,line)){
cout复制构造函数可能会被删除,但移动构造函数是声明的且可访问的。当您从函数返回局部变量时,将首先执行重载解析,就像它是一个右值一样。它选择调用哪个c'tor。如果对象是可移动构造的(有一个可以绑定到右值引用的c'tor),代码将是格式良好的
即使完成了所有这些操作,RVO也可能被应用,对象根本不会移动。因此f
和input
虽然在不同的范围内,但将引用同一对象
这是C++14的要点。从C++17开始,由于保证了复制省略,甚至移动构造函数也不一定总是可用。如果您尝试返回纯右值,而不是指定的本地值,您会注意到这一差异。复制构造函数可能会被删除,但移动构造函数是声明和可访问的。当您返回loca时函数中的l变量,重载解析首先像右值一样执行。它选择调用哪个c'tor。如果对象是可移动构造的(具有可绑定到右值引用的c'tor),则代码的格式将良好
即使完成了所有这些操作,RVO也可能被应用,对象根本不会移动。因此f
和input
虽然在不同的范围内,但将引用同一对象
这就是C++14的要点。从C++17开始,由于保证了复制省略,甚至move C'tor也不必总是可用。如果您尝试返回纯右值,而不是指定的本地值,您会注意到这一差异。如果流不能复制,但可以移动,输入由move构造函数返回如果流
无法复制,但可以移动,输入
由move constructor返回。我猜测了一些类似的内容,但我试图将事实明确化。例如,它看起来不像是在调用move constructor,因为那里有一些打印语句没有显示。我最后的猜测是RVO,但我尝试了使用-fno elide构造函数禁用它是徒劳的。我有没有办法确定是什么特定功能导致了这一点?@gowrath-Print语句在哪里?您自己的代码移动ifstream
。我从std::ifstream中派生了自己的类ifstreamv,以便打印调用了哪种类型的构造函数。实际上,一些进一步的调查显示它是RVO,如果不是,则调用move构造函数。我通过在从enterFile()返回时设置运行时条件来禁用RVO方法,它在移动构造函数中打印了我的print语句:)我沿着这些线猜到了一些东西,但我试图使事实显式化。例如,它看起来不像是在调用移动构造函数,因为我在那里有一些未显示的print语句。我最后的猜测是RVO,但我尝试使用-fno el禁用它ide构造函数
无效。有什么方法可以确定导致这种情况的特定功能吗?@gowrath-Print语句在哪里?您自己的代码移动了一个ifstream
。我从std::ifstream中派生了自己的类ifstreamv,以便打印调用了哪种类型的构造函数。实际上,一些进一步的调查显示了这一点是RVO,如果不是,则调用移动构造函数。我通过在enterFile()方法返回时设置运行时条件禁用了RVO,并且它在移动构造函数中打印了我的print语句:)
ifstream enterFile(){
ifstream input("hello.txt");
return input;
}
int main() {
ifstream f = enterFile();
string line;
while(getline(f, line)) {
cout << line << endl;
}
cout << "===== Done" << endl;
return 0;
}