3
prog.cpp:9:13: error: ‘result_type’ does not name a type
prog.cpp:9:13: note: (perhaps ‘typename std::unary_function<_Arg, _Result>::result_type’ was intended)

Compiler: http://ideone.com/vttG8W

Why cannot I use result_type directly?

#include <functional>

using namespace std;

template <typename ARGUEMENT, typename RESULT>
class FunctorBase : public std::unary_function<ARGUEMENT, RESULT>
{
public:
    virtual result_type operator () (argument_type) = 0;
        FunctorBase() {}
        virtual ~FunctorBase() {}
};

int main()
{
    FunctorBase<int&, void>();
}
Praetorian
  • 106,671
  • 19
  • 240
  • 328
Neil Kirk
  • 21,327
  • 9
  • 53
  • 91

3 Answers3

3

Because result_type and argument_type depend on the template parameters. Use:

virtual typename std::unary_function<ARGUEMENT, RESULT>::result_type
  operator () (typename std::unary_function<ARGUEMENT, RESULT>::argument_type) = 0;

or, if you need it in more places, add

using typename std::unary_function<ARGUEMENT, RESULT>::result_type;
using typename std::unary_function<ARGUEMENT, RESULT>::argument_type;

in the beginning of your class.

Daniel Frey
  • 55,810
  • 13
  • 122
  • 180
3

Because it is an unqualified name.

When you use unqualified names in a class template, you have to tell the compiler that it should not immediately search for global names during the first phase of the two-phase name lookup, but rather wait until instantiation (because the name could come from a base class, as is the case here).

In this case, you could do this (and make result_type a dependent, qualified name):

typedef typename std::unary_function<ARGUEMENT, RESULT>::result_type result_type;

Notice that the same applies to argument_type.

typedef typename std::unary_function<ARGUEMENT, RESULT>::argument_type argument_type;

Armed with those two typedefs, the original member function declaration will now compile:

virtual result_type operator () (argument_type) = 0;
Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
0

You can re-typedef it in your class:

typedef typename std::unary_function<ARGUEMENT, RESULT>::result_type my_result_type;

(You can even rename it the exact same thing) This is can work even if what you inherit from is private.

This compiles:

template <typename blah>
class MyTemplateBaseClass
{
    public: 
    typedef blah my_blah_typedef;
};

template <typename arg>
class DerivedFromTemplated : private MyTemplateBaseClass<arg>
{
public:
    //Either giving the full name:
    typename MyTemplateBaseClass<arg>::my_blah_typedef GetBlahType()
    {
        return typename MyTemplateBaseClass<arg>::my_blah_typedef();
    }

    //Or typedef-ing it locally:
    typedef typename MyTemplateBaseClass<arg>::my_blah_typedef my_blah_typedef;
    my_blah_typedef GetBlahType2()
    {
        return my_blah_typedef();
    }
};

int main()
{
    DerivedFromTemplated<int> test;
}
Jamin Grey
  • 10,151
  • 6
  • 39
  • 52