Cannot convert from 'Type' to 'const Type&' error with templates
Hello,
I encountered strange compilation error, so I want to hear
what other people say before I blame the compiler.
My environment: VC++2005, XP/Win2K.
I made helper function, which helps to build predicates for
many standard algorithms. The point of the function is that
it compares certain member of the class instead of whole
class object. Here's the code:
---------
////////////////////////////////////////////
// Template class for composition f(g(x))
template<typename F, typename G>
class compose_t :
public std::unary_function<
typename G::argument_type,
typename F::result_type
>
{
public:
explicit compose_t(const F& f, const G& g)
: m_f(f), m_g(g) {}
typename F::result_type operator()(
const typename G::argument_type& x) const
{
return m_f(m_g(x));
}
private:
F m_f;
G m_g;
};
// Template function to construct compose_t
template<typename F, typename G>
compose_t<F, G> compose(const F& f, const G& g)
{
return compose_t<F, G>(f, g);
}
////////////////////////////////////////////
// Sample class
struct X
{
X(const char* s, int n) : s_(s), n_(n) {}
const std::string& GetS() const { return s_; }
std::string s_;
int n_;
};
////////////////////////////////////////////
// Helper function to form arbitrary predicate
template <
typename T,
typename Func,
typename Pred
compose_t<std::binder2nd<Pred>, Func>
mem_match(
const T& val,
Func fn,
Pred pr = std::equal_to<T>()
)
{
return compose(std::bind2nd(pr, val), fn);
}
////////////////////////////////////////////
//
int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
{
typedef std::vector<X> XVec;
XVec v;
v.push_back(X("one", 1));
v.push_back(X("two", 2));
v.push_back(X("three", 3));
XVec::iterator it = std::find_if(
v.begin(), v.end(),
mem_match(
std::string("two"),
std::mem_fun_ref(&X::GetS)
)
);
return 0;
}
---------
The problem is that mem_match doesn't compile. Compiler
issues error C2783: could not deduce template argument for
'Pred'.
So, now I tried this one:
template <
typename T,
typename Func
compose_t<std::binder2nd<std::equal_to<T> >, Func>
mem_match(const T& val, Func fn)
{
return compose(
std::bind2nd(
std::equal_to<T>(), val), fn);
}
This compiles without any problem, however I cannot control
std::equal_to predicate from the outside of mem_match.
I cannot specify std::binary_function as template parameter
for std::binder2nd, since std::binary_function doesn't have
operator() at all, and compiler rightfully complains about
it.
How can I control predicate for mem_match?
Thanks in advance
Alex