lmi
[Top][All Lists]
Advanced

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

Re: [lmi] Default values for default arguments


From: Vadim Zeitlin
Subject: Re: [lmi] Default values for default arguments
Date: Sat, 4 Feb 2017 19:22:07 +0100

On Sat, 4 Feb 2017 17:23:19 +0000 Greg Chicares <address@hidden> wrote:

GC> On 2017-02-04 14:59, Vadim Zeitlin wrote:
...
GC> >  Personally I'm a bit wary of everything involving std::initializer_list 
in
GC> > C++, it's too simple to write something that compiles without any warnings
GC> > but doesn't behave like you thought it would with it (of course, the worst
GC> > offender here is the notorious std::vector<int> ctor, but there are other
GC>                                              ^^^
GC> I believe you mean std::vector<bool>.

 No, I really meant std::vector<int> and the reason why it's so special is
explained at https://herbsutter.com/2013/05/09/gotw-1-solution/ (see the
answer for the question 2).

GC> > examples too). So while it is convenient to use it in these 2 particular
GC> > (and, admittedly, very common) cases, I'm not sure it's worth the extra
GC> > potential for confusion that it creates.
GC> 
GC> Thanks for the explanation. I find it so ugly to write
GC>         ,std::vector<std::string> const& a_allowed_keywords = 
std::vector<std::string>()

 I think having a declaration such as

        using string_vector = std::vector<std::string>;

really helps when the same container type is used more than a couple of
times and with it this argument declaration would become quite reasonable:

        ,string_vector a_allowed_keywords = string_vector()

GC> Consider:
GC> 
GC>     ,std::string const&              w = std::string() // quote above
GC>     ,std::string const&              w = ""            // alternative
GC> 
GC> I'd like to choose one and use it uniformly throughout lmi. I think
GC> the former is better because it means "a default-constructed string",

 I do think the former is better but mostly because it's more uniform, the
tiny performance gain is probably not noticeable in any meaningful
benchmark anyhow.

GC> whereas the later, although shorter, means
GC>   create a one-element array of char in memory, containing '\0'
GC>   and then construct a string from that
GC> and I'm not sure the compiler can elide that. AIUI, in this case:
GC>   std::string a = std::string();
GC>   std::string b = std::string();
GC> &a might equal &b (and probably does),

 The optimizer might merge these objects somehow, but if you really try to
compare &a and &b in C++ code they're guaranteed to be different.

GC> I would propose to change the last two to "= std::string()".

 Agreed.

 The next question is, of course, whether it should be "= std::string()" or
"= std::string{}". The arguments in favour of using "{}" given at the URL
in the beginning of this message seem solid enough, but I have a lot of
trouble actually starting to use "{}" everywhere. Mostly this is because I
mostly work on existing projects which use "()" extensively and I can't
justify changing all of its occurrences to "{}", but, admittedly, also
because of my initializer_list-phobia: in addition to the issue with
std::vector<int> and other classes with similar ctors, consider that

        auto z{99};

doesn't do what you think it does, whatever you think it is, depending on
the C++ version. The long term good news is that it at least does what I
(and, I think, most C++ programmers) would expect it to do since C++17, but
in the short term this makes it even more confusing.

 However, again, the advantages of using "{}" are quite real: disallowing
narrowing conversions is definitely nice (although most compilers will, or
at least can, warn about them) and never running into the most vexing parse
again is quite appreciable as well. So maybe we should make an effort and
switch to using it in lmi?

 Regards,
VZ


reply via email to

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