Re: Dispatching on different fonctions according to template signature for containers doesn't work (yet) on G++
screetch wrote:
The code below allows one to find if a value is in an stl container
based on the type of the container :
//----------------------------------------------------------------
//set like containers
template< typename CONTENTTYPE,
typename COMPARATOR,
typename ALLOC,
template < typename, typename, typename > class CONTAINER >
inline bool IsInContainer(const CONTAINER<CONTENTTYPE, COMPARATOR,
ALLOC>& parContainer, const CONTENTTYPE& parValueToFind)
{
return parContainer.find(parValueToFind) != parContainer.end();
}
//map like containers
template< typename KEYTYPE,
typename CONTENTTYPE,
typename COMPARATOR,
typename ALLOC, template < typename, typename, typename,
typename > class CONTAINER >
inline bool IsInContainer(const CONTAINER<KEYTYPE, CONTENTTYPE,
COMPARATOR, ALLOC>& parContainer, const KEYTYPE& parValueToFind)
{
return parContainer.find(parValueToFind) != parContainer.end();
}
//vector like containers
template< typename CONTENTTYPE,
typename ALLOC,
template<typename, typename> class CONTAINER >
inline bool IsInContainer(const CONTAINER<CONTENTTYPE, ALLOC>&
parContainer, const CONTENTTYPE& parValueToFind)
{
return std::find(parContainer.begin(), parContainer.end(),
parValueToFind) != parContainer.end();
}
//----------------------------------------------------------------
the code builds fine under visual c++ but fails to build with GCC below
4.2 (so, basically, all versions of GCC) : for instance, with a set
container, both the vector-like and the set-like methods match. from
http://gcc.gnu.org/gcc-4.1/changes.html, i understand that gcc matches
the third parameter of the set template with the default value, which is
not in the c++ standard.
i'd like to know if there is a workaround for this bug so that we can
still dispatch methods according to the type of the containers. any help
would be appreciated, thanks :)
It is possible to apply a SPINAE technique (in the form of an extra
parameter with a default value) to determine whether the container's
allocator type is the second, third or fourth parameter type in its
template parameter list (corresponding to a vector, set and map,
respectively.)
#include <map>
#include <set>
#include <vector>
// vector like containers
template< typename T,
class Alloc,
template<class,class> class Container>
inline bool
IsInContainer( const Container<T, Alloc>&c,
const T& parValueToFind,
typename Alloc::pointer = NULL )
{
return std::find(c.begin(),c.end(),parValueToFind) != c.end();
}
//----------------------------------------------------------------
// set like containers
template< class T,
class Comp,
class Alloc,
template <class,class,class> class Container>
inline
bool IsInContainer(const Container<T, Comp, Alloc>&c,
const T& parValueToFind,
typename Alloc::pointer = NULL)
{
return c.find(parValueToFind) != c.end();
}
//----------------------------------------------------------------
// map like containers
template< typename Key,
typename T,
typename Comp,
typename Alloc,
template <class, class, class, class> class Container>
inline
bool IsInContainer( const Container<Key,T,Comp,Alloc>&c,
const Key& parValueToFind,
typename Alloc::pointer = NULL)
{
return c.find(parValueToFind) != c.end();
}
int main()
{
std::map<int, int> m;
bool b = IsInContainer(m, 5);
std::set<int> s;
b = IsInContainer(s, 3);
std::vector<int> v;
b = IsInContainer(v, 2);
}
Greg
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]