Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

templated operator() overload C++

someone already asked this question, but the thread ended up with the original question not getting answered.

suppose you have this:

template<size_t i, class f_type>
void call_with_i(f_type f);

functor_type is either:

a) a struct with a method that has the following signature:

template<size_t i> operator()() const;

or, b) a function that looks like this:

template<size_t i> foo();

I want "call_with_i<42>(foo)" to be equivalent to "foo<42>()", but I can't figure out the right syntax to make that happen. I'd be satified with a solution that does just (a) but (a)+(b) would be great. I've already tried these syntaxes:

f< i >(); // doesn't work
f()< i >; // doesn't work
f.operator< i >(); // doesn't work
f.operator()< i >; // doesn't work
f.operator()< i >(); // works on msvc, but doesn't work on gcc. 

How do you invoke operator() with explicit template arguments? Is there a way to invoke it in a way that the same syntax would also call a templated free function?

p.s. If you're wondering what i'm using this for, its because I'm writing a function repeat_to where repeat_to<10>(f) invokes f(0) then f(1) ... f(10). I'm using this to iterate through multiple boost::fusion vectors in parallel by index. yeah, i could use iterators, or i could just use a named member function, but i still want to know the answer.

edit note: i striked out stuff because passing a templated free function as an arg doesn't make any sense.

like image 316
Glenn Avatar asked Nov 19 '09 09:11

Glenn


People also ask

How do you call a template operator?

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).

What do you mean by operator overloading in C++?

Operator Overloading in C++ This means C++ has the ability to provide the operators with a special meaning for a data type, this ability is known as operator overloading. For example, we can overload an operator '+' in a class like String so that we can concatenate two strings by just using +.


1 Answers

The member template is a dependent name, because its semantics depend on the type of f_type. That means you should put "template" before its name (to disambiguate the use of the "less-than" token), similar to how you should put typename before dependent qualified names:

template<size_t i, class f_type>
void call_with_i(f_type f) {
  f.template operator()<i>();
  // f.template foo<i>();
}

As a workaround, you may use a helper type:

template<size_t N> struct size_t_ { }; // or boost::mpl::int_

template<size_t i, class f_type>
void call_with_i(f_type f) {
  f(size_t_<i>());
}

Now, you could define your operator() as follows:

template<size_t i> void operator()(size_t_<i>) const {
  // i was deduced automatically by the function argument. 
}

This comes handy for templated constructors, for which you cannot do f_type()<i>() or something. They will have to be deducible in that case.

like image 124
Johannes Schaub - litb Avatar answered Oct 01 '22 07:10

Johannes Schaub - litb