From: Edward Rosten on
On Feb 23, 8:00 pm, SG <s.gesem...(a)gmail.com> wrote:

> It depends on how you implement your Vector<> class template. It seems
> your vector's dimension is part of its type which suggests that you
> intend to store an array directly in the vector object (as member).

Also, gcc understands stack allocated arrays rather well and will
happily perform the optimization for you. It doesn't understand heap
allocated arrays well enough (yet) to do that.

> But I'm not sure about the usefulness of the std::initializer_list
> type. I mean, yes, it'll further simplify toy/example programs like
>
> map<string,string> phonebook = {
> {"William Tanner", "555-8531"},
> {"Ghostbusters","555-2368"}
> };
>
> but I have a hard time imagining something like this in real code
> where data comes from user inputs, files, or other sources.

Keeping in the theme of things, I (reasonably) often write things
like:

Vector<double, 3> axis = {1,0,0};

naturally, initializer lists make life easier. Also, the code I posted
in another thread about set-intersections, I originally wrote in C+
+0x, in order to get initializer lists to make debugging easier. Sure,
the final code didn't use them, but it definitely increased my
development speed.

> Also, the size information is not part of the list's type. In many
> cases this is a good thing. But in your example you expect 3 elements
> in the initializer list. If it's more or less than 3 you'll get an
> error *at runtime* which could have been detected at *compile-time* if
> the size of the initializer list was somehow part of its type.

Yes the size is not part of the type, however, the size could in
theory be a constexpr. This would be every bit as useful (unless I
have missed something), but I don't know if it is going to be a
constexpr in the final standard, and I can't figure it out either way.
If it is not, is it reasonable to call it a defect and make a defect
report?

-Ed

--
(You can't go wrong with psycho-rats.)(http://mi.eng.cam.ac.uk/~er258)

/d{def}def/f{/Times s selectfont}d/s{11}d/r{roll}d f 2/m{moveto}d -1
r 230 350 m 0 1 179{ 1 index show 88 rotate 4 mul 0 rmoveto}for/s 12
d f pop 235 420 translate 0 0 moveto 1 2 scale show showpage

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: SG on
On 24 Feb., 01:18, "Hak...(a)gmail.com" <hak...(a)gmail.com> wrote:
> On Feb 23, 3:00 pm, SG <s.gesem...(a)gmail.com> wrote:
> > On 23 Feb., 03:51, "Hak...(a)gmail.com" <hak...(a)gmail.com> wrote:
> > > [...]
> > But rvalue references would not help you in such cases (unless the
> > array's elements can be moved much faster than copied). Rvalue
> > references are great in case "logical members" are heap-allocated and
> > only referenced through a pointer member (see std::vector, for
> > example).
>
> The way i use rvalue references is in the operator+ function:
>
> // Pseudo code
> template< T1, T2, S >
> Vector<T2,S>&& operator+( const Vector<T1,S>& a, Vector<T2,S>&& b )
> {
> b += a;
> return std::move(b);
> }
>
> Rather than creating a vector with a+b, then another with (a+b)+c, it
> should create a temporary with a+b, then add c onto (a+b), then copy
> that into d.

You mean a+(b+c), right? Only the 2nd parameter of this operator+
function is an rvalue reference. Anyhow, I'd consider it unsafe and it
is likely not worth the hassle of writing this overload. I would guess
that this doesn't safe any significant amount of time (Have you
measured it?). It's unsafe because it allows you to write things like

auto const& foo = a + (b + c);

where foo would be a dangling reference. In my opinion, one should try
to avoid writing functions that return references to argument objects
which could have been temporaries.

The current draft N3035 still contains some operator+ functions for
strings which return rvalue references. But my understanding is that
this is going to be replaced. See LWG issue #1138:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3018.html#1138

> > [...]
> > I'm just doing a little thinking out loud here but maybe an
> > inheritance relationship is not such a bad idea:
> >
> > template<class T>
> > class initializer_list
> > {
> > // insert implementation here
> > public:
> > T* begin() const;
> > T* end() const;
> > };
> >
> > template<class T, size_t N>
> > class fixed_size_initlist : public initializer_list<T>
> > {
> > };

Just to clarify: The idea is an object of this type family (instead of
initializer_list<T>) would be generated by the compiler for a list
initializer "expression".

> > template<class T, size_t Dim>
> > class myvector
> > {
> > T coefficients[Dim];
> > public:
> > explicit myvector(std::fixed_size_initlist<T,Dim> initlist);
> > etc.
> > };
>
> That fixed-size list is EXACTLY what i wish was supported. And,
> really, ctors taking initializer lists could just template the size as
> well and no functionality would be lost... except for how the compiler
> would be generating a new version of the ctor for each different size.

It the size doesn't matter you could still use initializer_list.
That's the idea of the inheritence relationship. Every
fixed_size_list<T,N> *is* an initializer_list<T> which also makes the
first one convertible to the second one. So, you would have the choice
of selecting between one of

void foo1(std::initializer_list<double> il) {
assert(il.size() == 3);
...
}

void foo2(std::fixed_size_initlist<double,3> il) {
...
}

The other problem I have with std::initializer_list is that I don't
understand what happens in cases like this:

// This is supposed to work as far as I can tell.
// range will be of type std::initializer_list<int>
auto && range = {rand(),rand(),rand()};

Suddenly an initialization list can survive past the end of a full
expression. What happens to their elements? How long do they live?
Where do they live? What does a typical implementation look like? ...
Also, Bjarne Stroustrup once answerd the question whether
initializer_lists could be returned from functions with a "Yes". I can
only come to the conclusion that you need something like a heap
allocated array of elements + reference counting for the elements to
live long enough.

Cheers,
SG
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Mathias Gaunard on
On Feb 24, 12:18 am, "Hak...(a)gmail.com" <hak...(a)gmail.com> wrote:

> The way i use rvalue references is in the operator+ function:
>
> // Pseudo code
> template< T1, T2, S >
> Vector<T2,S>&& operator+( const Vector<T1,S>& a, Vector<T2,S>&& b )
> {
> b += a;
> return std::move(b);
>
> }

This realize this modifies its right operand, which isn't something
operator+ should do?
Did you mean to only apply that to non-lvalues?


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Pedro Lamarão on
Hakusa(a)gmail.com wrote:

> What C++0x features are most relevant to you? I'm curious about what
> others consider good features to know, but mostly which they actually
> want to use. I am personally invested in rvalue references,
> std::thread, and std::initializer_list.

Rvalue references have been the most useful to me so far.

It has simplified much code around "device" like classes, because it
allowed me to make them non-copyable yet still usable with all generic
components I need.

Before rvalue references I was in a constant state of doubt about
whether to make them non-copyable; both options would bring me pain.

In second place comes auto, which is just excellent. One day, visiting
the Museum of Programming, young people won't believe that old people
had to state explicitly the long type name of the indexer in a for
loop.

--
P.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Seungbeom Kim on
Pedro Lamar�o wrote:

> In second place comes auto, which is just excellent. One day, visiting
> the Museum of Programming, young people won't believe that old people
> had to state explicitly the long type name of the indexer in a for
> loop.

Typing the long name was doable, but it has kept me perplexed how
I should align the text when the 'for' statement goes multiple lines:

for (std::map<std::string, int>::const_iterator i = member_ages.begin();
i != member_ages.end(); ++i) {
// body
}

No matter how I did it, it wasn't satisfactory. :(

(The main source of the complaint is that both the continuing lines
inside ( ) in the 'for' statement and the loop body should be indented,
and they are not very readily distinguished. And yes, I prefer to have
the opening brace at the end of the 'for' line.)
--

Seungbeom Kim

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]