lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] [io]fstream move ctors


From: Greg Chicares
Subject: Re: [lmi] [io]fstream move ctors
Date: Sat, 1 May 2021 00:57:36 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.9.0

On 4/30/21 9:48 PM, Vadim Zeitlin wrote:
> On Fri, 30 Apr 2021 20:11:37 +0000 Greg Chicares <gchicares@sbcglobal.net> 
> wrote:
> 
> GC> Vadim--Please help me understand why clang considers the [io]fstream
> GC> move ctors to be deleted (cf. the [squashed] commit below).
> 
>  First of all, let me start by showing the problem in a simple test case:
> 
> ---------------------------------- >8 --------------------------------------
> % cat -n fstest.cpp
>      1  #include <fstream>
>      2
>      3  struct my_stream final : public std::ifstream
>      4  {
>      5      my_stream() = default;
>      6      my_stream(my_stream const&) = delete;
>      7      my_stream(my_stream&&) = default;
>      8  };
> % clang++-12 -std=c++20 -stdlib=libc++ -fsyntax-only -Wall fstest.cpp
> fstest.cpp:7:5: warning: explicitly defaulted move constructor is implicitly 
> deleted [-Wdefaulted-function-deleted]
>     my_stream(my_stream&&) = default;
>     ^
> /usr/lib/llvm-12/bin/../include/c++/v1/istream:177:7: note: move constructor 
> of 'my_stream' is implicitly deleted because base class 'basic_ios<char>' has 
> a deleted move constructor
>     : virtual public basic_ios<_CharT, _Traits>
>       ^
> /usr/lib/llvm-12/bin/../include/c++/v1/ios:603:7: note: copy constructor of 
> 'basic_ios<char>' is implicitly deleted because base class 'std::ios_base' 
> has an inaccessible copy constructor
>     : public ios_base
>       ^
> 1 warning generated.
> ---------------------------------- >8 --------------------------------------

Suppose we add to that example (so that gcc also reports errors):

  int main(int, char*[])
  {
    std::ifstream a;                // 1 okay
    std::ifstream b(a);             // 2 error
    std::ifstream c(std::move(a));  // 3 okay

    my_stream s;                    // 4 okay
    my_stream t(s);                 // 5 error
    my_stream u(std::move(s));      // 6 error
  }

In the first set, using std::ifstream:

 - Somehow #2 doesn't surprise me--I dimly recall that we're
   supposed to construct from a copy of the other stream's
   streambuf...or something like that. If I need to do it,
   I look it up; I do that so rarely that I don't try to
   remember.

 - #3 kind of surprises me. If #3 and #6 were both errors,
   that would seem natural enough to me. Given that one is
   an error and the other is not, it's #3 that seems
   surprising: moving works when copying doesn't. Well, I
   guess they do something in the move ctor to make that
   work. The streambuf or whatever it's called is a raw
   pointer, but I guess it's more like a unique_ptr than a
   shared_ptr. What I see through a glass darkly satisfies
   my curiosity well enough, because after all why should
   we care about moving or copying fstream objects?

>  So we have the choice between just deleting the move ctor, as I did
> because I thought we didn't need it anyhow and it was the simplest
> solution, or defining it explicitly.

I look with favor upon a third choice: use the rule of zero,
and don't try to specify, ourselves, what should be deleted
or defaulted. If we'd get those special member functions
automatically, then there's no reason to type "=default".

Otherwise, the compiler can't generate them; que serĂ¡ serĂ¡.
In that case, isn't writing "=delete" just redundant?

And if we never even try to use them (as is likely), then
we don't have to think about any of this.

>  To summarize, it still seems like the simplest thing to do is to keep the
> current version, without any move ctor at all, and even though the original
> commit description was misleading. But if we want to define this move ctor,
> we could do it, probably using swap().
> 
>  Please let me know if you think it's worth doing this,

No. I don't see any use case for either moving or copying
an fstream object anyway.

But thanks for the explanation.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]