Dinesh
Dinesh

Reputation: 1866

C++ template for function call operator

I tried to use template for function call operator overload as in the following program:

#include <stdio.h>

struct Apple
{
   template <typename tn> tn value ();
   template <typename tn> tn operator () ();
};

template <> int Apple::value ()
{
   return 10;
}

template <> int Apple::operator () ()
{
   return 10;
}

int main()
{
   Apple apple;
   printf("Value : %d\n", apple<int>());
   printf("Value : %d\n", apple.value<int>());   
   return 0;
}

While value function call in the second print does not show any error the function call operator in the first print show expected primary-expression error. I don't know what I am doing wrong. Can anyone help me know the problem thanks in advance.

Upvotes: 10

Views: 7183

Answers (1)

vsoftco
vsoftco

Reputation: 56547

The problem is when invoking a templated operator() (second line of main()). In your case, you need to explicitly specify the return type, as it cannot be deduced, and the correct way of doing it is:

printf("Value : %d\n", apple.operator()<int>());

operator()() is a template member function that takes () as parameters. So, its name is operator(), its parameter list is (). Therefore, to refer to it, you need to use apple.operator() (its name), followed by <int> (template parameter), then followed by () (parameter list). Replace mentally the name operator() with FUNCTION, so operator()() is FUNCTION(), and you'll see the pattern. In your case, apple<int>() is invoking a non-template operator()() on a template instantiation apple<int> object, i.e. apple<int>.operator()(), which is not what you want.

Useful to define such an operator? Probably not, as it leads to ugly syntax.


You can achieve what you probably want by using auto return type in C++14, like

#include <stdio.h>

struct Apple
{
   template <typename tn> tn value ();
   auto operator () ();
};

template <> int Apple::value ()
{
   return 10;
}

auto Apple::operator () () // not a template anymore, return type is deduced int
{
   return 10;
}

int main()
{
   Apple apple;
   printf("Value : %d\n", apple());
   printf("Value : %d\n", apple.value<int>());   
   return 0;
}

In this example, auto doesn't really shine, as you may manually specify int as the return type, but in more complicated declaration can be really useful.

Upvotes: 15

Related Questions