tags:

views:

65

answers:

1

I am confused about the strange syntax provided by C++ function templates and class templates. Take a quick look at the code below:

#include <iostream>
#include <algorithm>
#include <functional>
#include <iterator>
#include <vector>
using namespace std;

template <class op1,class op2>
class compose_fg_x_t : public unary_function<typename op2::argument_type,typename op1::result_type>{
public:
// constructor

compose_fg_x_t(const op1& arg1,const op2& arg2): p1(arg1),p2(arg2){
}
//function call
typename op1::result_type operator()(const typename op2::argument_type& x) const{
    return p1(p2(x));
  }

private:
op1 p1;
op2 p2;

};

template <class Op1,class Op2>
inline compose_fg_x_t<Op1,Op2> compose_fg_x(const Op1& p1,const Op2& p2){
    return compose_fg_x_t<Op1,Op2>(p1,p2);
}
int main(int argc, char *argv[])
{
int a[] = {1,2,3,4,5};
vector<int> IntVec(a,a+sizeof(a)/sizeof(int));
copy(IntVec.begin(),IntVec.end(),ostream_iterator<int>(cout," "));
cout<<endl;
transform(IntVec.begin(),IntVec.end(),ostream_iterator<int>(cout,"    "),compose_fg_x( bind2nd(multiplies<int>(),5),bind2nd(plus<int>(),10) ));
transform(IntVec.begin(),IntVec.end(),ostream_iterator<int>(cout," "),compose_fg_x_t(   bind2nd(multiplies<int>(),5),bind2nd(plus<int>(),10) ));
return 0;
}

So, my question is, why is the first transform is correct while the second is not? What the helper function compose_fg_x does is return an object of the underlying compose_fg_x_t type. I am trying to omit the indirect function call, which fails to compile. Why?

+4  A: 

Template arguments can only be deduced for function templates, not for class templates. The whole point of helper functions such as make_pair (or your compose_fg_x) is to circumvent this limitation.

Here is a slightly less complicated example that demonstrates the problem:

#include <utility>

int main()
{
    auto x = std::make_pair(3, 4);   // function template arguments are deduced
    auto y = std::pair(3, 4);        // error: missing class template arguments
}
FredOverflow
thanks,but then it is somewhat inconvenient and inefficient.
Tracy
@Tracy: It's slightly inconvenient to have to write the helper functions, but not inefficient. Any half-decent compiler will inline the function call and produce identical code in both cases.
Mike Seymour