Re: N2215: Size 0 initializer lists
Daniel Kr?gler ha scritto:
IMO at least in case of the N2215 paper, I strongly propose,
that the empty initializer list is *always* valid and would simply
invoke the default c'tor (whether generated or not) or empty
sequence c'tor. Since the notion is new and explicit, I see no
reasons for possible unwanted performance killers, because the
old style is also valid and can be used, if really wanted.
Agreed, but see below...
This extension would also solve a problem in explicit specializations
of static data members, which I came aware by reading
"C++ Templates" (1st ed, p. 198). Consider:
class DefaultInitOnly {
public:
DefaultInitOnly(){}
private:
DefaultInitOnly(const DefaultInitOnly&);
};
template<typename T>
class Statics {
static T sm;
};
template<>
DefaultInitOnly Statics<DefaultInitOnly>::sm; // Declaration, *no*
// definition!
template<>
DefaultInitOnly Statics<DefaultInitOnly>::sm =
DefaultInitOnly(); // Copy c'tor not available!
That is, in current C++ we have no valid syntax for
such a static data member definition. The following
would solve this problem:
template<>
DefaultInitOnly Statics<DefaultInitOnly>::sm = {}; // (a) Should work?
(not yet)
template<>
DefaultInitOnly Statics<DefaultInitOnly>::sm{}; // (b) Should work?
(not yet)
Yup! That's precisely the issue I had in mind.
And yes, I'm aware of the ambiguity problem between
default c'tor and empty sequence c'tor invokation (discussed
and resolved in the paper). According to my interpretation, the
rules explained in section 4.1 of N2215 would simply result into
the case 1.2.1 of the case flow chart.
I would rather not fit the empty initializer list case in the general
rule described in 4.1. I believe that the simply stating "an empty
initializer list always means value-initialization" is easier to
understand and explain.
In order to make this principle work, I came to conclusion that the root
point here is in the definition of default constructor, which predates
the idea of initializer lists. The definition currently is (12.1/5): "A
default constructor for a class X is a constructor of class X that can
be called without an argument." [Note - I believe this definition is not
as good as it can be, because more than one constructor might satisfy
the condition at the same time. However, in such case none of them could
be used as THE default constructor, because it would be ambiguous. What
is the point in putting the "default constructor" label to something
that can't be used as such? - End note]
Back to the point, does an initializer-list-constructor satisfy the
requirement? What do we want it to be? There are pros and cons.
I see two options. The first one is that ctor taking an initializer list
cannot be called without arguments, so they can never be default
constructors. This has the advantage that I can make a
non-default-constructible class with an initializer-list-ctor (whether
this is reasonable/useful I don't know). The disadvantage is that if
have the "an empty initializer list always means value-initialization"
rule, then the programmer must write a default constructor explicitly.
The second option is to amend the definition of default constructor this
way:
1) A class type with user defined constructors has either one or no
default constructor. If it exists, the default constructor shall be
unambiguously selected in all contexts where an object is constructed
with no arguments or in presence of an empty initializer list.
2) In order to determine the default constructor, all constructors that
don't take initializer lists are considered:
1) if there is exactly one constructor that can be called with no
arguments, it's the default constructor
2) otherwise, if there are more than one constructors that can be
called with no arguments, there is no default constructor
3) otherwise, if there is exactly one constructor that take initializer
list, it is the default constructor
4) otherwise, there is no default constructor.
This definition, together with the "an empty initializer list always
means value-initialization" rule, has the following advantages:
a) a class that can has exactly one constructor taking an initializer
list does not need to define another constructor to be
default-constructible.
b) removes the "I have two default constructors therefore none of them"
embarrassment.
Any thoughts?
Ganesh
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]