1
template <typename elemType, typename Comp = less<elemType> >
class LessThanPred {
    public:
        LessThanPred(const elemType &val) : _val(val){}
        bool operator()(const elemType &val) const
        { return Comp(val, _val); }
        void val(const elemType &newval) { _val = newval; }
        elemType val() const { return _val; }
private:
    elemType _val;};

That's an example from Essential c++. Comp is obviously a function object class name. Why could I use the Comp(val, _val) directly? Normally I think I should firstly define a function object like this: Comp comp, then invoke comp not Comp.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
yycfox
  • 13
  • 2
  • Comp is a type parameter, not a function object class name. By the way, you can actually define a `Comp comp` object and then invoke `comp`. – user2296177 Nov 04 '15 at 19:47
  • Did you instantiate/use the function call operator of `LessThanPred`? Since it is a template member it gets checked for correctly only when instantiated. – Dietmar Kühl Nov 04 '15 at 19:50
  • I'm voting to close this question as off-topic because The citation is not correct –  Nov 04 '15 at 19:58
  • @DieterLücking: section 6.7 "Template Parameters as Strategy" of "Essential C++" (1st printing) does contain that exact code. – Dietmar Kühl Nov 04 '15 at 20:00
  • Hence I am wrong (wtf, trusting) –  Nov 04 '15 at 21:30

1 Answers1

1

The code as is compiles because the template members are only checked for semantic correctness when they are instantiated. The code is syntactically well-formed, though. However, when you try to instantiate the function call operator of LessThanPred<T>, you'll get a compiler error. For example, with the version of clang (3.6.1) I'm using I get

less-than.cpp:8:18: error: no matching constructor for initialization of 'std::less<int>'
        { return Comp(val, _val); }
                 ^    ~~~~~~~~~
less-than.cpp:17:25: note: in instantiation of member function 'LessThanPred<int, std::less<int> >::operator()' requested here
    LessThanPred<int>(2)(1);

when trying to use the function as

LessThanPred<int>(2)(1)
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • For the default situation, could I change the code ' { return Comp(val, _val); }' into { return Comp()(val, _val); }? – yycfox Nov 04 '15 at 22:26