Re: N2215: Size 0 initializer lists
[Note: This is a reposting of an answer some days ago, I hope
it's not too outdated now]
Alberto Ganesh Barbati schrieb:
Cool, so we finally have an explicit syntax for value-initialization?
But... wait... just a few paragraph below, in the same section it is said:
"A class with a generated default constructor can co-exist with
initializer list initialization. However, this would be an error:
struct SS {
SS() { }
string a, b;
};
SS ss0 = { }; // error:"
so it seems to me that the intent of the last statement of the previous
paragraph " we don't have to worry about whether a type is implemented
as a built-in or a user-defined type" is, at least in part, defeated.
What am I missing?
I have the same problem. And regrettably this limitation invalidates
some of the paper's own promises, e.g. on page 22 we have:
"A more interesting example might be
Map<string,int> m = { {"ardwark",91}, {"bison", 43} };
Assuming that map has a sequence constructor for from a
pair<string,int>, this will work, correctly converting the literal
strings to strings."
According to the specs of std::pair, the default constructor
is *not* the generated one, so consequently this should not
work.
One the other side, it also seems not reasonable to add
the constructor
template <class T1, class T2>
struct pair {
..
template <typename U>
pair(std::initializer_list<U>);
};
not only, because this would only support homogenous
pairs, but additionally we have to handle list sizes > 2.
(OK, provided that the size() member function *is* a
constexpr, we can do this:
template <typename U>
pair<T1, T2>::pair(std::initializer_list<U> src)
first((static_assert(src.size() == 2, "Invalid initializer"),
src[0])),
second(src[2])
{
}
but that seems somewhat horrible). To be fair, we must
recognize that Beman Dawes stumbled across similar
restrictions in his POD-extension proposal,
http://www2.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2172.html
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.
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)
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.
Greetings from Bremen,
Daniel Kr?gler
---
[ 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 ]