Topic: Delayed objects.


Author: Michiel.Salters@cmg.nl (Michiel Salters)
Date: Fri, 1 Nov 2002 13:40:06 CST
Raw View
bob.news@gmx.net (Robert Klemme) wrote in message news:<3DC017AA.EA9AEF0A@gmx.net>...
> Ram'on Garc'ia Fern'andez schrieb:
> >
> > The purposal of this proposal is to solve the problem of having to
> > construct an object before adding it to a vector.
[ SNIP ]
> > ... instead of vector.push(object) one writes vector.push(function)
> > where function is defined as:
> [snip]
>
> why extend the language when there are these solutions?
>
>  a) pointers as container members.
>
>  b) reference counted instances with smart pointers as container
> members
>
>  c) using proxies that delegate the real functionality to some
> other instance

Because these constructs won't create vectors of contiguous objects,
for instance. (But that's mostly important for POD objects, which
have cheap copy ctors.)

Because the objects are small and numerous, so the proxy overhead is
very large.

On the other hand, we already have this functionality, albeit
indirectly. It's the templated insert, which takes an iterator range.
The producer function mentioned above is simply the iterator's
operator* method.

Regards,
--
Michiel Salters

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]





Author: John Nagle <nagle@animats.com>
Date: Sat, 2 Nov 2002 16:45:31 CST
Raw View
    This is one of the dark corners of C++.

    1.  Objects in STL collections have to be copyable.
    2.  If the object isn't easily copyable, it's usually
 necessary to "new" each object separately and
 maintain a collection of pointers to it.
    3.  auto_ptr would seem to be the ideal mechanism
 for that, but collections of auto_ptr don't work.
    4.  Alternatively, you could write collections which allow
 in-place construction, but passing a variable
 number of arguments to a "new" contained within
 a template is difficult.

Thus, one must suffer.

    John Nagle
    Animats

Michiel Salters wrote:

> bob.news@gmx.net (Robert Klemme) wrote in message news:<3DC017AA.EA9AEF0A@gmx.net>...
>
>>Ram'on Garc'ia Fern'andez schrieb:
>>
>>>The purposal of this proposal is to solve the problem of having to
>>>construct an object before adding it to a vector.
>

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]





Author: andrewalex@hotmail.com ("Andrei Alexandrescu")
Date: Sun, 3 Nov 2002 17:36:41 +0000 (UTC)
Raw View
"Michiel Salters" <Michiel.Salters@cmg.nl> wrote in message
news:cefd6cde.0211010143.407016bc@posting.google.com...
> On the other hand, we already have this functionality, albeit
> indirectly. It's the templated insert, which takes an iterator range.
> The producer function mentioned above is simply the iterator's
> operator* method.

The idea was to not assign the vector elements in any way. The iterators, on
the other hand, will be dereferenced and used for initializing vector
elements.

std::vector<POD> is in dire need of an efficient resize mechanism.


Andrei


---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pasa@lib.hu ("Balog Pal")
Date: Mon, 4 Nov 2002 04:36:14 +0000 (UTC)
Raw View
""Andrei Alexandrescu"" <andrewalex@hotmail.com> wrote in message news:aq0vh2$5ijts$1@ID-14036.news.dfncis.de...

> The idea was to not assign the vector elements in any way. The iterators, on
> the other hand, will be dereferenced and used for initializing vector
> elements.
>
> std::vector<POD> is in dire need of an efficient resize mechanism.

Hmm. I recently noticed [from the source code] CArray of the MFC library (I'd guess a widely used thing) moves objects using memcpy.  I found nothing mentioning this behavior, nor a set of requirements on TYPE I supposed to use with the temlate to make it work correctly. Wow.

As a matter of fact I used it for quite a period, and a plenty of fellow programmers, and never got burned.  That made me think to create a 'correct' implementation that uses some other tech on resize, and thinking the cases when the currebt implementation fails and the new one will not.
To my surprise my list got extremely thin:
-  when the object has internal pointers/refs

Certainly the other, more likely case would be when someone else holds pointer to the object, but in practice I don't use such pointers with vecor-like containers, only with stable ones, like list.

I guess other people already thought about these issues, so a more complete list of ill cases (or a pointer to the info source) would help me much.   As currently I decided the memcpy tech, even though makes me feel bad, can stay.

Paul

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]





Author: bob.news@gmx.net (Robert Klemme)
Date: Wed, 30 Oct 2002 20:28:46 +0000 (UTC)
Raw View

Ram'on Garc'ia Fern'andez schrieb:
>
> The purposal of this proposal is to solve the problem of having to
> construct an object before adding it to a vector. This adds the cost
> of moving an object. Though the Mojo proposal partially solves the
> problem by adding a faster way of moving an object, moving has an
> intrinsic cost that can be avoided.
>
> The solution consists that, instead of passing an object, one passes
> something that allows an object to be built, a function that returns
> an object.
>
> So instead of vector.push(object) one writes vector.push(function) where
> function is defined as:
[snip]

why extend the language when there are these solutions?

 a) pointers as container members.

 b) reference counted instances with smart pointers as container
members

 c) using proxies that delegate the real functionality to some
other instance

i.e. where is the benefit that is big enough that it would
justify a language change?  currently i can't see it but this
might be due to my lack of understanding.

regards

 robert

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]





Author: bob.news@gmx.net (Robert Klemme)
Date: Mon, 4 Nov 2002 17:54:43 +0000 (UTC)
Raw View

Balog Pal schrieb:
> As a matter of fact I used it for quite a period, and a plenty of fellow programmers, and never got burned.  That made me think to create a 'correct' implementation that uses some other tech on resize, and thinking the cases when the currebt implementation fails and the new one will not.
> To my surprise my list got extremely thin:
> -  when the object has internal pointers/refs

what about pointers between instances in the vector?  i guess,
this would create problems, too.  although this is quite similar
to external pointers to elements in a vector which you should'n
use as you pointed out.

> Certainly the other, more likely case would be when someone else holds pointer to the object, but in practice I don't use such pointers with vecor-like containers, only with stable ones, like list.

regards

 robert

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]





Author: nagle@animats.com (John Nagle)
Date: Tue, 5 Nov 2002 17:27:35 +0000 (UTC)
Raw View
Balog Pal wrote:
 > Hmm. I recently noticed [from the source code] CArray of the MFC
 > library (I'd guess a widely used thing) moves objects using memcpy.

   That goes back a long way, back to at least 1996.
Templates barely worked at all in MFC back then.

     John Nagle
     Animats

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]





Author: ramon@jl1.quim.ucm.es (Ram'on Garc'ia Fern'andez)
Date: Tue, 22 Oct 2002 17:51:36 +0000 (UTC)
Raw View
The purposal of this proposal is to solve the problem of having to
construct an object before adding it to a vector. This adds the cost
of moving an object. Though the Mojo proposal partially solves the
problem by adding a faster way of moving an object, moving has an
intrinsic cost that can be avoided.

The solution consists that, instead of passing an object, one passes
something that allows an object to be built, a function that returns
an object.

So instead of vector.push(object) one writes vector.push(function) where
function is defined as:

class function<T> {
   T operator()() {};
   };

   class myfunction<T> : public function<T> { ....};

The language should provide a reasonable method for building this
function. The proposed extension consists in adding a new keyword,
delayed. When this keyword is used, the lowest precedence operation of
the expression is not evaluated, instead a function that performs the
evaluation is generated. For instance:

   x = delayed y + z;

creates a function that evaluates y + z and returns the result.

Now you pass x:

   vector.push_back(x);

when the implementation of push_back puts x into the vector, at this
time x() is evaluated and the result inserted directly into the
vector.

This proposal is inspired in ML delayed objects.

Ramon

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]





Author: allan_w@my-dejanews.com (Allan W)
Date: Wed, 23 Oct 2002 02:39:52 +0000 (UTC)
Raw View
ramon@jl1.quim.ucm.es (Ram'on Garc'ia Fern'andez) wrote
> The purposal of this proposal is to solve the problem of having to
> construct an object before adding it to a vector. This adds the cost
> of moving an object. Though the Mojo proposal partially solves the
> problem by adding a faster way of moving an object, moving has an
> intrinsic cost that can be avoided.
>
> The solution consists that, instead of passing an object, one passes
> something that allows an object to be built, a function that returns
> an object.
>
> So instead of vector.push(object) one writes vector.push(function) where
> function is defined as:
>
> class function<T> {
>    T operator()() {};
>    };
>
>    class myfunction<T> : public function<T> { ....};
>
> The language should provide a reasonable method for building this
> function. The proposed extension consists in adding a new keyword,
> delayed. When this keyword is used, the lowest precedence operation of
> the expression is not evaluated, instead a function that performs the
> evaluation is generated. For instance:
>
>    x = delayed y + z;
>
> creates a function that evaluates y + z and returns the result.
>
> Now you pass x:
>
>    vector.push_back(x);
>
> when the implementation of push_back puts x into the vector, at this
> time x() is evaluated and the result inserted directly into the
> vector.
>
> This proposal is inspired in ML delayed objects.

I wonder if we couldn't solve the same problem more directly. The
problem is that the vector always uses either default constructor or
copy constructor to add a new element. If we could control which
constructor was used, we could simply ask whoever creates the element
to do so in the vector.

One way to do this is to add a new function to vector, perhaps called
"newaddr". This function would extend the size of the vector as if it
had just constructed a new element, and then return the address of that
element so that the caller can construct it with placement new.

    // Construct new myobj object directly in myvec
    new(myvec.newaddr()) myobject(1,2,3);

A simpler, perhaps less error-prone version would be to add new
template member functions that construct the object as requested.

    // Construct new myobj object directly in myvec as element 25
    myvec.construct(25,1,2,3); // 1,2,3 passed to constructor

Without having tried it, I suspect that this is possible today --
except that construct() would have to be overloaded with various
numbers of arguments, which would limit the number you could use.

    // Version with 3 constructor arguments...
    template<typename T>template<typename A,typename B,typename C>
    vector<T>::construct(size_t element, A a, B b, C c) {
        T *t = newaddr(); // Common code decides where to build it
        new(t) T(a,b,c);
    }
    // ...etc for other numbers of arguments...

I think that some people have already proposed extensions to the
template mechanism (varargs for template arguments?) which would
simplify this.

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]