|
Boost : |
From: Hamish Mackenzie (boost_at_[hidden])
Date: 2002-02-19 13:21:17
On Tue, 2002-02-19 at 10:38, Peter Dimov wrote:
> From: "Hamish Mackenzie" <boost_at_[hidden]>
> > I thought this was solved by Koenig lookup?
> >
> > using std::swap;
> > swap( x, y );
> >
> > Then Koenig lookup will find swap if it is in the namespace that x and y
> > are in will it not?
>
> http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2001/n1296.htm
>
> In short, yes it will. This is error-prone, though (experts have been known
> to get that wrong) and it doesn't solve the problem within the standard
> library, i.e. std::sort using std::swap (without additional guarantees.)
Ok, I think my proposed swap.hpp in the other post fixes the std::
problem. It is similar to the fix described in the section "Enable
argument-dependent lookup on standard names" except it allows you to
still call it std::swap (rather than std::iter_swap). Unfortunately it
still has all the same problems described which you could argue are due
to the misuse of overloading.
All this talk of typeof and auto, makes me worry that overloading is
going to be used even more in the future simply because it means less
typing (as in pressing of keys) when often it should not be used because
it means less typing (as in type saftey is lost).
I would much rather line an easier way to write the equivalent of the
following prolog code
some_type( TypeValue1 ) :- ...
some_function( some_type( TypeValue1 ), some_type( TypeValue2 ),
ReturnValue ) :- ...
In C++ it is
// Function class
template< typename T1, typname T2 >
class some_function_type;
// Runtime helper
template< typename T1, typname T2 >
typename some_function_type<T1,T2>::return_type some_function(
const T1 & a, const T2 & b )
{
return some_function_type<T1,T2>::execute( a, b );
}
// Define types of type this and may have more
// than one template argument (eg std::vector<T,A> )
template< typename TypeValue1 >
class some_type_type {...};
// Specialize class
template< typename TypeValue1, typname TypeValue2 >
class some_function_type<
some_type_type< TypeValue1 >,
some_type_type< TypeValue2 > >
{
public:
// Compile time version
typedef some_compile_time_expression return_type;
// Runtime version
static return_type execute(
const some_type_type< TypeValue1 > & a,
const some_type_type< TypeValue2 > & b )
{
...
}
};
No wonder people want to use overloading instead of specialization.
Thats not to say we can do without overloading for instance if you want
to define some_function for some_base class and all its derived classes
you need to write
typename some_function_type<some_base, some_base>::return_type
some_function( const some_base & a, const some_base & b )
{
return some_function_type<some_base,some_base>::execute( a, b );
}
You could add do_some_function for overloading by people outside your
namespace but because it returns a value some_function will not be able
to determine the return type for derived classes. Here typeof or auto
would be useful but it still would not fix the fact that three lines of
prolog have become rather a lot of C++.
Hamish Mackenzie
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk