$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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