开发者

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)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜