Re: Trying to apply SFINAE
Hendrik Schober wrote:
Victor Bazarov wrote:
Hendrik Schober wrote:
[...]
Well, the compiler cannot deduce the type from a default argument, I
vaguely recall that it's a non-deducible context. That's why putting
the traits there won't cut it. Consider
#include <iterator>
template<typename Iter>
void test(Iter, Iter, std::iterator_traits<Iter> const* = 0);
int main ()
{
const int fa[] = { 1,2,3,4 };
test(fa, fa+4);
}
Thanks! However, while the above works, this doesn't:
#include <iterator>
template< typename T >
void test( T /*a1*/, T /*a2*/ ) {}
template< typename Iter >
void test( Iter /*b*/, Iter /*e*/
, std::iterator_traits<Iter> = std::iterator_traits<Iter>()
) {}
int main()
{
const int fa[] = { 255, 255, 255, 255 };
test(0,1);
test(fa, fa+4);
return 0;
}
(Both VC and Comeau complain it's ambiguous.) But that's
just what I need.
They are probably correct :-/
Let's try to involve a class where you can make a partial specialisation:
template<class T, bool> struct ActualWorker; // "abstract"
template<class T> struct ActualWorker<T,false> // non-iterator
{
static void test(T /*a1*/, T /*a2*/) { /*whatever*/ }
};
template<class T> class ActualWorker<T,true> // iterator
{
static void test(T /*i1*/, T /*i2*/) { /*whatever*/ }
};
// now - how do we determine it's an iterator?
template<class T> struct IsIterator { enum { yes = 0 }; };
template<class T> struct IsIterator {
... // here you need to add some way to set 'yes' to 1
... // if 'T' is an iterator. It's up to you to define
... // what is an iterator and what isn't.
};
template<class T> void test(T t1, T t2) {
return ActualWorker<T, IsIterator<T>::yes >::test(t1, t2);
}
int main()
{
test(42, 666);
int foo[] = { 1,2,3,4 };
test(foo, foo+4);
}
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask