Re: Automatic function result type adaption depending on arg?
On Mar 7, 9: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'd rather avoid using Boost enable_if (or any Boost dependency).
Is there some reason not to overload startOf as below? This is
similar to the way I tend to add operator<<()...
Cheers,
Tony
#include <cassert>
#include <iostream>
#include <vector>
template< typename T >
inline typename T::iterator startOf( T& c )
{
std::cout << "startOf(T& c) returning T::iterator\n";
return c.begin();
}
template< typename T >
inline typename T::const_iterator startOf( T const& c )
{
std::cout << "startOf(const T& c) returning T::const_iterator\n";
return c.begin();
}
template< typename T, size_t N >
inline T* startOf( T (&a)[N] )
{
std::cout << "startOf(T (&a)[N]) returning a\n";
return a;
}
struct X
{
typedef const int* Const_Iterator;
typedef int* Iterator;
X(int a, int b) { a_[0] = a; a_[1] = b; }
Const_Iterator first() const { return a_; }
Iterator first() { return a_; }
friend Const_Iterator startOf(const X& x) {
std::cout << "startOf(const X&) returning X::Const_Iterator
\n";
return x.first();
}
friend Iterator startOf(X& x) {
std::cout << "startOf(X&) returning X::Iterator\n";
return x.first();
}
int a_[2];
};
int main()
{
std::vector<int> i;
i.push_back(4);
i.push_back(10);
assert(*startOf(i) == 4);
const std::vector<int>& ci = i;
assert(*startOf(ci) == 4);
int ai[2] = { 4, 10 };
assert(*startOf(ai) == 4);
X x(4, 10);
assert(*startOf(x) == 4);
const X& cx = x;
assert(*startOf(cx) == 4);
}