Reputation: 3224
I noticed that I am able to return a std::ifstream
from a function by value without the compiler giving me any errors related to a deleted copy constructor. This shouldn't work because ifstreams shouldn't be copyable so I imagine it is inlining the function in some way? Does anyone have an explanation for this?
I am running Mac OSX El Capitan 10.11.6 with Apple LLVM version 7.3.0 (clang-703.0.31) g++
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;
}
Upvotes: 1
Views: 116
Reputation: 170084
The copy constructor may be deleted, but the move constructor is declared and accessible. When you return a local variable from a function, overload resolution is first performed as though it was an rvalue. That chooses which c'tor to call. If the object is move constructible (has a c'tor that can bind to an rvalue reference), the code will be well formed.
Even after all that is done, the RVO is probably applied and the object isn't moved at all. So f
and input
, though in different scopes, will refer to the same object.
That's the gist of it up to C++14. From C++17 onward even the move c'tor need not always be available, thanks to guaranteed copy elision. You'd notice this difference if you try to return a pure rvalue instead if a named local.
Upvotes: 5