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 >(); // does开发者_StackOverflow中文版n'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.
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.
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.
#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)
精彩评论