+8  A: 

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.

Johannes Schaub - litb
@Johannes: why not specialize for functions using SFINAE?
Konrad Rudolph
works great! totally awesome. you're my meta-hero.ah, and your idea bout using mpl::int_ is smart too.
Lau Lau Labs
@laulaulabs.mp, glad to be of help :)
Johannes Schaub - litb
I found like @laulaulabs.mp that trying to pass function templates like that does not make sense. So that workaround using `size_t_` is questionable in this scenario. Modified the answer accordingly.
Johannes Schaub - litb
A: 
#include <iostream>

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

struct A {

    template < size_t i >
    void operator()() const {
     /* no link err in demo */
    }

    template < size_t i >
    void foo() {
     /* no link err in demo */
    }
};

int main(int argc, char * const argv[]) {
    A f;

    enum { Constant = 42 };

    f.operator()<Constant>();
    f.foo<Constant>();

    return 0;
}

Is there a way to invoke it in a way that the same syntax would also call a templated free function?

Can you clarify? (pseudocode, or something)

Justin
actually my bit about the templated free function is just nonsense since you can't pass a function template as an argument.
Lau Lau Labs
+1  A: 

In a case like yours I would use boost::function as functor type. You can then pass both function objects and function pointers while retaining the same interface.

UncleZeiv