Re: Automatic function result type adaption depending on arg?
On Mar 7, 2:33 am, "Alf P. Steinbach" <al...@start.no> wrote:
I have e.g.
template< typename T >
inline typename T::iterator startOf( T& c )
{
return c.begin();
}
template< typename T >
inline typename T::const_iterator startOf( T const& c )
{
return c.begin();
}
template< typename T, Size N >
inline T* startOf( T (&a)[N] )
{
return a;
}
Types from the standard library use 'iterator' and 'const_iterator', but =
imagine
some other large set of types TheirOwnWay with e.g. 'Iter' and 'ConstIter=
', and
that those types are in numeruous different namespaces.
How can the functions above be modified so that it's simple to make them =
work
also with TheirOwnWay types, e.g. by defining some type trait thing?
I tried the to me "obvious" customization hook, like
template< typename T >
inline typename IterTrait<T>::T startOf( T& c ) ...
keeping the last overload above as-is, but this failed spectacularly when
calling startOf(a) where a is a raw array.
I came up with the code below. CProxy would have to be specialized for
non standard containers (as for array). Unfortunately one needs the
extra call to c_proxy function template to resolve T, but IMO bettern
than specifying the template parameter:
#include <vector>
template <class T>
struct CProxy
{
typedef typename T::iterator iterator;
typedef T& ContRefT;
explicit CProxy( ContRefT c ): c_( c ){}
ContRefT c_;
};
template <class T, int N>
struct CProxy<T(&)[N]>
{
typedef T* iterator;
typedef T(&ContRefT)[N];
struct ArrayWrapper
{
ArrayWrapper( ContRefT c ): c_( c ){}
iterator begin() const { return &c_[0]; }
//...end etc...
ContRefT c_;
};
explicit CProxy( ContRefT c ): c_( c ){}
ArrayWrapper c_;
};
template <class ContT>
CProxy<ContT> c_proxy( ContT c )
{
return CProxy<ContT>( c );
}
template <class T, int N>
CProxy<T(&)[N]> c_proxy( T(&a)[N] )
{
return CProxy<T(&)[N]>( a );
}
template< typename T >
inline typename CProxy<T>::iterator
startOf( CProxy<T> cproxy )
{
return cproxy.c_.begin();
}
int main()
{
char array[5];
char* a =
startOf( c_proxy(array) );
const std::vector<char> vect;
std::vector<char>::iterator b =
startOf( c_proxy(vect) );
}
Kind regards,
Werner
I'd rather avoid using Boost enable_if (or any Boost dependency).
Cheers,
- Alf