Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 835
Dinesh Avatar asked Mar 06 '15 13:03

Dinesh


People also ask

How do you call a function in a template?

A function template starts with the keyword template followed by template parameter(s) inside <> which is followed by the function definition. In the above code, T is a template argument that accepts different data types ( int , float , etc.), and typename is a keyword.

How do you call a function operator?

The function call operator is denoted by “()” which is used to call function and pass parameters. It is overloaded by the instance of the class known as a function object. When the function call operator is overloaded, an operator function is created that can be used to pass parameters.

Can we overload () operator?

These operators can be overloaded globally or on a class-by-class basis. Overloaded operators are implemented as functions and can be member functions or global functions. An overloaded operator is called an operator function. You declare an operator function with the keyword operator preceding the operator.

What is the correct syntax of defining function template template functions?

What is the correct syntax of defining function template/template functions? Explanation: Starts with keyword template and then <class VAR>, then use VAR as type anywhere in the function below. 7.


1 Answers

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.

like image 182
vsoftco Avatar answered Sep 21 '22 11:09

vsoftco