Reputation: 14869
I would like to use algorithm std::include
to work with heterogeneous STL collections. In my example I would like to check if a std::vector
of integer is included in a std::map
.
I would like to solve this problem by using a simple templated function; the reason for this is because I would like to use the C++ template argument deduction to let deduce when first argument of the comparer function is a std::pair vs an int and the other way around ( std::include
behind the scenes calls Comp(a,b) and Comp(b,a) ).
Below my code I would like to run
typedef std::map<int,std::string> dict;
typedef std::vector<int> vect;
int data[]={1,2,3,4};
vect l(data,data+4);
dict h;
h.insert(dict::value_type(0,"ciccio"));
h.insert(dict::value_type(1,"ciccio"));
std::includes( h.begin(),h.end()
, l.begin(), l.end(), is_my_less );
I tried the following below but it doesn't compile and say partial specialization is not allowed
but also unresolved overloaded function type
that makes me think that I am doing something wrong with my function.
Do you know is that is possible by using strictly a templated function?
template<class T1,class T2,class T3>
bool is_less_than_pair( const T1&a ,const T2& b ){
return false;
};
template<class T1,class T>
bool is_less_than_pair<
T1
, std::pair<T1,T>
, T >( const T1&a, const std::pair<T1,T>& b ){
return a<b.first;
}
template<class T1, class T>
bool is_less_than_pair<
std::pair<T1,T>
,T1
, T >( const std::pair<T1,T>& a, const T1& b ){
return a.first<b;
}
Now based on the fact that function templates cannot be partially specialized I tried function overloading like below but it didn't work out and gcc tells me unresolved overloaded function type
again. What is the best I can do?
template<class T1,class T2>
bool is_less_than_pair( const std::pair<T1,T2>& a ,const T1& b ){
return a.first<b;
};
template<class T1,class T2>
bool is_less_than_pair( const T1& a ,const std::pair<T1,T2>& b ){
return b.first<a;
};
Upvotes: 0
Views: 210
Reputation: 21123
If you're restricted to functions, no. You can't use an overloaded function, because it won't be able to select the proper overload when passing it to the STL algorithm. And you can't partially specialize a function template.
It can be done with a function object, by providing all of the overloads. In effect, you'll pass all of the overloads to the STL algorithm, and then it will choose the appropriate overload as it's called. Note, due to the fact that the map's values are std::pair<const int, string>&
, use of the same T1 in both sides of the mixed-mode operators will not work, since the vector's iterators are turning int&, where the map's are using a constant.
struct my_less_than
{
template <typename T1>
bool operator()(const T1& lhs, const T1& rhs) const
{
return lhs < rhs;
}
template <typename T1, typename T2, typename T3>
bool operator()(const T1& lhs, const std::pair<T2, T3>& rhs) const
{
return lhs < rhs.first;
}
template <typename T1, typename T2, typename T3 >
bool operator()(const std::pair<T1, T2>& lhs, const T3& rhs) const
{
return lhs.first < rhs;
}
template <typename T1, typename T2, typename T3>
bool operator()(const std::pair<T1, T2>& lhs, const std::pair<T1, T3>& rhs) const
{
return lhs.first < rhs.first;
}
};
Usage:
std::includes( h.begin(),h.end()
, l.begin(), l.end(), my_less_than() );
Edit: Example http://ideone.com/JFIoy
Upvotes: 4