C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Template Specialization

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Senthilvel
Guest





PostPosted: Mon Jun 28, 2004 8:14 am    Post subject: Template Specialization Reply with quote



Hi folks,
I was trying to learn the standard library algorithms where i got stuck with
the templates.

I wrote one function to eliminate the duplicates(from The C++ Programming
Language 3rd Edition)

template<class Con> void RemoveDuplicates(Con& seq)
{
sort(seq.begin(),seq.end());
typename Con::iterator p = unique(seq.begin(),seq.end());
seq.erase(p,seq.end());
}

int main()
{
vector<int> ls1;
ls1.push_back(1);
ls1.push_back(2);
ls1.push_back(3);
ls1.push_back(4);
ls1.push_back(1);
ls1.push_back(2);
ls1.push_back(3);
ls1.push_back(4);

print_all(ls1,cout);

RemoveDuplicates(ls1);

print_all(ls1,cout);

return 0;

}

This worked fine for vector,deque but failed for list as sort needs randon
access iterators which is not provided by list

So i thought of specializing the function for list, but how do i do it ???
List needs a template argument and i do not know how to pass that
template argument.I did this way

template<class T> void RemoveDuplicates(list<T> & seq)
{
seq.sort();
typename list<T>::iterator p = unique(seq.begin(),seq.end());
seq.erase(p,seq.end());
}

int main()
{
list<int> ls1;
ls1.push_back(1);
ls1.push_back(2);
ls1.push_back(3);
ls1.push_back(4);
ls1.push_back(1);
ls1.push_back(2);
ls1.push_back(3);
ls1.push_back(4);

print_all(ls1,cout);

RemoveDuplicates<int>(ls1);

print_all(ls1,cout);




return 0;

}

Now i explicity need to specify the type in the RemoveDuplicates function.
Am i correct or am i missing something ???


Thanks and Best Regards,
Senthilvel.



Back to top
Sumit Rajan
Guest





PostPosted: Mon Jun 28, 2004 8:55 am    Post subject: Re: Template Specialization Reply with quote




"Senthilvel" <Senthil (AT) nospam (DOT) com> wrote

Quote:
Hi folks,
I was trying to learn the standard library algorithms where i got stuck
with
the templates.

I wrote one function to eliminate the duplicates(from The C++ Programming
Language 3rd Edition)

template<class Con> void RemoveDuplicates(Con& seq)
{
sort(seq.begin(),seq.end());
typename Con::iterator p = unique(seq.begin(),seq.end());
seq.erase(p,seq.end());
}

int main()
{
vector<int> ls1;
ls1.push_back(1);
ls1.push_back(2);
ls1.push_back(3);
ls1.push_back(4);
ls1.push_back(1);
ls1.push_back(2);
ls1.push_back(3);
ls1.push_back(4);

print_all(ls1,cout);

RemoveDuplicates(ls1);

print_all(ls1,cout);

return 0;

}

This worked fine for vector,deque but failed for list as sort needs randon
access iterators which is not provided by list

So i thought of specializing the function for list, but how do i do it ???
List needs a template argument and i do not know how to pass that
template argument.I did this way

template<class T> void RemoveDuplicates(list<T> & seq)
{
seq.sort();
typename list<T>::iterator p = unique(seq.begin(),seq.end());
seq.erase(p,seq.end());
}

int main()
{
list<int> ls1;
ls1.push_back(1);
ls1.push_back(2);
ls1.push_back(3);
ls1.push_back(4);
ls1.push_back(1);
ls1.push_back(2);
ls1.push_back(3);
ls1.push_back(4);

print_all(ls1,cout);

RemoveDuplicates<int>(ls1);

print_all(ls1,cout);




return 0;

}

Now i explicity need to specify the type in the RemoveDuplicates function.
Am i correct or am i missing something ???


Thanks and Best Regards,
Senthilvel.

You could try something like this:


#include <iostream>
#include <vector>
#include <algorithm>
#include <list>

template<class Con> void RemoveDuplicates(Con& seq)
{
std::sort(seq.begin(),seq.end());
typename Con::iterator p = std::unique(seq.begin(),seq.end());
seq.erase(p,seq.end());
}

template<class T> void RemoveDuplicates (std::list<T>& lst)
{
lst.sort();
typename std::list<T>::iterator p = std::unique(lst.begin(),lst.end());
lst.erase(p,lst.end());

}


int main()
{
std::list<int> ls1;
ls1.push_back(1);
ls1.push_back(2);
ls1.push_back(3);
ls1.push_back(4);
ls1.push_back(1);
ls1.push_back(2);
ls1.push_back(3);
ls1.push_back(4);

std::copy(ls1.begin(),ls1.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << 'n';

RemoveDuplicates(ls1);

std::copy(ls1.begin(),ls1.end(),
std::ostream_iterator std::cout << 'n';

}


Regards,
Sumit.



Back to top
Senthilvel
Guest





PostPosted: Mon Jun 28, 2004 9:33 am    Post subject: Re: Template Specialization Reply with quote



------> By Senthil
Quote:

template<class Con> void RemoveDuplicates(Con& seq)
{
sort(seq.begin(),seq.end());
typename Con::iterator p = unique(seq.begin(),seq.end());
seq.erase(p,seq.end());
}

template<class T> void RemoveDuplicates(list<T> & seq)
{
seq.sort();
typename list<T>::iterator p = unique(seq.begin(),seq.end());
seq.erase(p,seq.end());
}


------> By Sumit

Quote:
template<class Con> void RemoveDuplicates(Con& seq)
{
std::sort(seq.begin(),seq.end());
typename Con::iterator p = std::unique(seq.begin(),seq.end());
seq.erase(p,seq.end());
}

template<class T> void RemoveDuplicates (std::list<T>& lst)
{
lst.sort();
typename std::list<T>::iterator p =
std::unique(lst.begin(),lst.end());
lst.erase(p,lst.end());

}


Thats exacty what i have done Sumit...
I get the error
"error C2667: 'RemoveDuplicates' : none of 2 overload have a best
conversion"
"error C2668: 'RemoveDuplicates' : ambiguous call to overloaded function"
on the line
RemoveDuplicates(ls1);
in main
Sad
BTW..I am using MS -VC++ 6 compiler ..




Back to top
Sumit Rajan
Guest





PostPosted: Mon Jun 28, 2004 9:33 am    Post subject: Re: Template Specialization Reply with quote


"Senthilvel" <Senthil (AT) nospam (DOT) com> wrote


Quote:
BTW..I am using MS -VC++ 6 compiler ..


Well, it compiles using VC++ 7.1 and Comeau C++ 4.3.3. I guess it
VC++ 6.0 does not extend full support to overloading templates (but I'm not
sure as I have never used 6.0).

Regards,
Sumit.



Back to top
Alf P. Steinbach
Guest





PostPosted: Mon Jun 28, 2004 10:01 am    Post subject: Re: Template Specialization Reply with quote

* Senthilvel:
Quote:

template<class Con> void RemoveDuplicates(Con& seq)
{
sort(seq.begin(),seq.end());
typename Con::iterator p = unique(seq.begin(),seq.end());
seq.erase(p,seq.end());
}

int main()
{
vector<int> ls1;
ls1.push_back(1);
ls1.push_back(2);
ls1.push_back(3);
ls1.push_back(4);
ls1.push_back(1);
ls1.push_back(2);
ls1.push_back(3);
ls1.push_back(4);

print_all(ls1,cout);

RemoveDuplicates(ls1);

print_all(ls1,cout);

return 0;

}

This worked fine for vector,deque but failed for list as sort needs randon
access iterators which is not provided by list

So i thought of specializing the function for list, but how do i do it ???
List needs a template argument and i do not know how to pass that
template argument.I did this way

template<class T> void RemoveDuplicates(list<T> & seq)
{
seq.sort();
typename list<T>::iterator p = unique(seq.begin(),seq.end());
seq.erase(p,seq.end());
}

int main()
{
list<int> ls1;
ls1.push_back(1);
ls1.push_back(2);
ls1.push_back(3);
ls1.push_back(4);
ls1.push_back(1);
ls1.push_back(2);
ls1.push_back(3);
ls1.push_back(4);

print_all(ls1,cout);

RemoveDuplicates<int>(ls1);

print_all(ls1,cout);
return 0;

}

Now i explicity need to specify the type in the RemoveDuplicates function.
Am i correct or am i missing something ???

No, you don't need to specify the type, it's inferred.

But your implementation is tied specifically to std::list.

It's generally better to separate the template requirements, e.g. like


#include <iostream>
#include <vector>
#include <list>
#include <algorithm>

template< class T >
struct HasRandomIterators_{ enum{ yes = true }; };

template< typename T >
struct HasRandomIterators_< std::list{ enum{ yes = false }; };

template< class Container, bool genericIsOK = true>
struct RemoveDuplicates_
{
static void from( Container& c )
{
std::sort( c.begin(), c.end() );
typename Container::iterator it = std::unique( c.begin(),
c.end() );
c.erase( it, c.end() );
}
};

template< class Container>
struct RemoveDuplicates_<Container, false>
{
static void from( Container& c )
{
c.sort();
c.unique();
}
};

template< class Container >
void removeDuplicates( Container& c )
{
RemoveDuplicates_<Container,
HasRandomIterators_::from( c );
}

template< class Container >
void printAll( Container const& c )
{
typedef Container::const_iterator Iterator;
for( Iterator it = c.begin(); it != c.end(); ++it )
{
std::cout << *it << std::endl;
}
}

int main()
{
std::list
c.push_back( 1 );
c.push_back( 2 );
c.push_back( 3 );
c.push_back( 4 );
c.push_back( 1 );
c.push_back( 2 );
c.push_back( 3 );
c.push_back( 4 );

printAll( c );
std::cout << std::endl;

removeDuplicates( c );
printAll( c );
}

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Back to top
Senthilvel
Guest





PostPosted: Mon Jun 28, 2004 10:18 am    Post subject: Re: Template Specialization Reply with quote

Quote:
No, you don't need to specify the type, it's inferred.

But your implementation is tied specifically to std::list.

It's generally better to separate the template requirements, e.g. like


#include <iostream
#include #include #include
template< class T
struct HasRandomIterators_{ enum{ yes = true }; };

template< typename T
struct HasRandomIterators_< std::list{ enum{ yes = false }; };

template< class Container, bool genericIsOK = true
struct RemoveDuplicates_
{
static void from( Container& c )
{
std::sort( c.begin(), c.end() );
typename Container::iterator it = std::unique( c.begin(),
c.end() );
c.erase( it, c.end() );
}
};

template< class Container
struct RemoveDuplicates_ {
static void from( Container& c )
{
c.sort();
c.unique();
}
};

template< class Container
void removeDuplicates( Container& c )
{
RemoveDuplicates_ HasRandomIterators_::from( c );
}

template< class Container
void printAll( Container const& c )
{
typedef Container::const_iterator Iterator;
for( Iterator it = c.begin(); it != c.end(); ++it )
{
std::cout << *it << std::endl;
}
}

Thanks Alf...Thats a nice technique...
But my only problem it does not compile on VC++ 6.0 : - (

error C2989: 'HasRandomIterators_
Quote:
' : template class has already been defined as a non-template class
error C2988: unrecognizable template declaration/definition

error C2989: 'RemoveDuplicates_<Container,0>' : template class has already
been defined as a non-template class
error C2988: unrecognizable template declaration/definition

Got to keep this in mind until we move to VC 7.0..(Hoping this code compiles
will compile in that version )



Back to top
John Harrison
Guest





PostPosted: Mon Jun 28, 2004 12:29 pm    Post subject: Re: Template Specialization Reply with quote

Quote:
Thanks Alf...Thats a nice technique...
But my only problem it does not compile on VC++ 6.0 : - (

error C2989: 'HasRandomIterators_<class std::list std::allocator ' : template class has already been defined as a non-template class
error C2988: unrecognizable template declaration/definition
error C2989: 'RemoveDuplicates_ been defined as a non-template class
error C2988: unrecognizable template declaration/definition

Got to keep this in mind until we move to VC 7.0..(Hoping this code
compiles
will compile in that version )



Alf was using partial template specialisation, which is not supported in
VC++ 6. I would leave off learning templates until you upgrade to VC++ 7.1
(not 7.0), VC++ 6 template support is poor and you'll only end up learning
stuff which isn't true.

John



Back to top
red floyd
Guest





PostPosted: Mon Jun 28, 2004 5:06 pm    Post subject: Re: Template Specialization Reply with quote

Senthilvel wrote:
Quote:
[redacted]

Your problem is MSVC6. VC6 is widely known (and acknowledged by MS) to
have problems with template specializations.

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.