Re: Algorithm template specialization problem
Sherrie Laraurens wrote:
I'm trying to write a generic algorithm routine that will
take begin and end iterators of a container, iterate through
the range and perform a "calculation" of sorts.
The trouble is that the algorithm will behave differently for
the two different types. I've considered calling the algorithm
foo_A and foo_B, but I don't like that approach because it will
blow out in naming complexity down the track.
I was hoping with partial specialisations, I could get something
happening, but I'm finding it difficult templating an iterator but
not knowing what "type" of iterator it is. Also another major
problem is the algorithm wont know what kind of type the classes
A or B will be specialised as.
I've considered using a function object, but the algorithm I'm trying
to perform is not a for_each style thing, it needs to go through all
the elements in the iterator range, do some things, then modify the
elements accordingly.
Sounds like a 'transform' analogue.
Some of the problem is see are:
1. Can't specialize on A or B properply without knowing their types
2. It would be unprofessional to have foo<T,A<T> >(v.begin,v.end)
below is what I've got so far, the code it pretty self explanatory,
but mind you it wont compile without errors.
template<typename T>
class A { public: T val; };
template<typename T>
class B { public: T val1; T val2; };
template< typename T,
typename P,
typename Iterator > class foo;
template<typename T, typename P = A<T>, typename Iterator>
You need to either move 'P' to the end or to give 'Iterator' its
default argument. I think you actually meant to specialise 'foo',
so here is what it should looke like:
template<typename T, typename Iterator>
class foo<T,A<T>,Iterator>
class foo
{
void operator()(Iterator begin, Iterator end)
{
for(Iterator it = begin, it != end; it++)
{
(*it).val++;
}
}
};
template< typename T, typename P = B<T>, typename Iterator>
Same default argument problem here.
class foo
{
void operator()(Iterator begin, Iterator end)
{
for(Iterator it = begin, it != end; it++)
{
(*it).val1++;
(*it).val2++;
}
}
};
Add here
int main(void)
{
std::vector< A<double> > vec1(100,1);
foo< A<double> >()(vec1.begin(),vec1.end());
std::vector< B<double> > vec2(100,1);
foo< B<double> >()(vec2.begin(),vec2.end());
return true;
}
I was hoping someone could give me some good ideas, tips
or a way to get what I want happening. I would appreciate
it very much.
I don't know if it's going to give you any ideas (I hope it doesn't give
you the wrong ones :-)) but it compiles for me on VC++ 2005 (although does
give some problems with Comeau online test:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template<typename T>
class A { public: T val; A(T t) : val(t) {} };
template<typename T>
class B { public: T val1; T val2; B(T t) : val1(t), val2(0) {} };
template<typename Iterator, typename V> class foo;
template<typename Iterator, typename T>
class foo<Iterator, A<T> >
{
public:
void operator()(Iterator begin, Iterator end)
{
for (Iterator it = begin; it != end; it++)
{
(*it).val++;
}
}
};
template<typename Iterator, typename T>
class foo<Iterator, B<T> >
{
public:
void operator()(Iterator begin, Iterator end)
{
for(Iterator it = begin; it != end; it++)
{
(*it).val1++;
(*it).val2++;
}
}
};
template<typename Iterator>
void do_foo(Iterator it1, Iterator it2)
{
foo<Iterator, Iterator::value_type> ft;
ft(it1, it2);
}
#include <vector>
int main()
{
std::vector< A<double> > vec1(100,1);
do_foo(vec1.begin(),vec1.end());
std::vector< B<double> > vec2(100,1);
do_foo(vec2.begin(),vec2.end());
return true;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask