Boost logo

Boost :

From: Jens Maurer (Jens.Maurer_at_[hidden])
Date: 2001-01-28 17:56:18


Here are a few initial comments. They should not discourage you, but
point out a few things for your further consideration.

jbandela_at_[hidden] wrote:
> Here is some code, that allows assigning and manipulating variables
> without knowing the exact type, but by knowing what expression
> produced them.

In general, the STL approach to that problem is by defining another
function call layer where the unknown type is a template parameter.
It is deduced during overload resolution, and the type of the
argument expression is thus "known" (rather instantiated) in the
function body. I do, however, recognize that it would be useful
to avoid that additional layer in some circumstances. Unfortunately,
the examples exposed are not template-heavy enought to really show
the benefit, which would possibly become more apparent when
expressions yield very complicated types, as those in expression
templates.

 - Please separate implementation (header file) from test/example program.
 - The whole thing needs boost-ification and documentation.
 - I'd like to see a feature comparison between this proposal and
the (boost-accepted) "any" class by Kevlin Henney.

> class Destructor{};

Needs a virtual destructor, I believe.
 
> template<class T>
> struct DestructorImp:public Destructor

Should be in namespace "boost::detail" and be referenced from the
"Memento" class internally.

> std::allocator<T> a;
> a.destroy(static_cast<T*>(o));

Is there any benefit from using std::allocator<> instead
of calling the destructor explictly right away, such as so:
  static_cast<T*>(o)->~T()
?

> template<class T>
> DestructorImp<T> GetDestructor(void* o, const T*){

The "const T*" parameter is superfluous, you can use explicit function
template instantiation. Yes, MSVC is broken in this regard, but
can be worked around.

> template<int sz>
> struct Memento{
> char mem_[sz];
> void* data_;
>
> template<class T>
> Memento(const T& object){
> T* o = new(static_cast<void*>(&mem_[0])) T(object);
> data_ = o;

_data will always contain &mem_[0] and is thus superfluous.

You need to cater for alignment requirements, which you don't currently.

> #define BOOST_TYPE(expr) (0?GetType((expr)):0)

Boost has been very reluctant in defining new function-style macros. Any
such macro needs a strong justification that its purpose cannot be fulfilled
with "normal" C++, e.g. templates. I'd like to see this justification
explicitly.
 
> #define BOOST_LET(var, expr,line) Memento<sizeof(expr)> var
> (expr);Destructor dd##line = GetDestructor(var.data_,BOOST_TYPE
> (expr)) ;

This is entirely unsatisfactorily, because it interferes with
conditional statements not containg a block.

  if( /* ... */ )
    BOOST_LET(...); // oops

Besides, the destruction can be integrated in Memento and then, I
believe, looks suspiciously like the "any" class.

Plus, explicitly requiring a "line" parameter is too error-prone.

> for(;y.get(BOOST_TYPE(v.begin())) != v.end();++y.get
> (BOOST_TYPE(v.begin())) )

This looks rather awkward to me, compared to a simple typedef
and a straightforward loop.

It would be really helpful if, given some expression "expr", the
type of this expression could be made available as a name, so
that
  typedef BOOST_TYPE(2.0*3) T;
gives you "double" for T.

This is why we need "typeof" in the core language.

Jens Maurer


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk