Function Template with an Operator

Function template with an operator

You need to specify T.

int i = c.operator()<int>();

Unfortunately, you can't use the function call syntax directly in this case.

Edit: Oh, and you're missing public: at the beginning of the class definition.

C++ template for function call operator

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.

operator << overloading in a template function

Before you can befriend specific template specialization, you have to declare the general template function first like this:

template <typename Value>
class Tree;

template <typename Value>
std::ostream& operator<<(std::ostream& os, Tree<Value> const& tree);

template <typename Value>
class Tree {
protected:
Node<Value>* root = NULL;
int size = 0;
std::ostream& _ostreamOperatorHelp(Node<Value>* node, int level,
std::ostream& os) {
...
}

public:
friend std::ostream& operator<< <Value>(std::ostream& os,
Tree<Value> const& tree);
};

template <typename Value>
std::ostream& operator<<(std::ostream& os, Tree<Value> const& tree) {
tree._ostreamOperatorHelp(tree.GetRoot(), 0, os);
return os;
}

How to write an insertion operator function template?

You've inadvertedly added a possible overload for const char* by making this:

template<typename T>
std::ostream& operator<<(std::ostream& osOut, T& tContainer)

If you narrow it down a bit with SFINAE, it should work.

This overload will only work for types with a getList() member function for example:

template<typename T, typename U = decltype(std::declval<T>().getList())>
std::ostream& operator<<(std::ostream& osOut, T& tContainer)

Function template with operator overloading

#include <iostream>

using namespace std;

template <typename type>
type Max(type a, type b)
{
return a > b ? a : b;
}

class Foo {
public:
string s1;
bool operator > (Foo &obj) {
return this->s1.length() > obj.s1.length();
}
};

int main()
{
cout << Max(2, 3) << endl;
cout << Max(2.0, 3.0) << endl;
Foo a, b;
a.s1 = "AB";
b.s1 = "ABC";
cout << Max(a, b).s1;
}

This maybe what you want: output results

How to call template operator?

There is no direct way

There is no syntax to form a template-id ([temp.names]) by providing
an explicit template argument list ([temp.arg.explicit]) for a
conversion function template

But there are options to choose from.

  1. Use a general member-function template instead. That's how std::tuple works.
  2. Create own template type convertible to bool. Define conversion operator to that type.
  3. Consider that you actually should do something else. Perhaps visitor pattern is what you're looking for.

Using a default template argument for a template conversion function to a non-template type OR using a template-id as target for conversion function are ONLY ways how one can pass a template-argument while instantiating and invoking said conversion function. E.g.:

class CChQuAuth {
public:
CChQuAuth() { }
};

template <typename T>
struct MyBool {
bool v;
operator bool() { return v;};
};

class CChQuCached {
public:
CChQuCached() {
}

template <typename T>
operator typename ::MyBool<T>();
};

template <typename T>
CChQuCached::operator typename ::MyBool<T>()
{
return MyBool<T>();
}

int main()
{
CChQuCached ChQuCached;

bool b = ChQuCached.operator MyBool<CChQuAuth>();
}

That's just an example and no way a proper boilerplate code. Note that conversion operator name expected to be a nested type-id first, and in this case it is given as fully qualified one, with ::.

Passing a reference to template function call operator overload

That's because in your case the cv-qualifiers and the reference-ness of the parameter are discarded when performing template type deduction. Pass via a std::ref wrapper instead

t(std::ref(i));

Simple example:

#include <iostream>
#include <functional>

template<typename T>
void f(T param)
{
++param;
}

int main()
{
int i = 0;
f(std::ref(i));
std::cout << i << std::endl; // i is modified here, displays 1
}


Related Topics



Leave a reply



Submit