开发者

templated operator() overload C++

开发者 https://www.devze.com 2022-12-11 17:28 出处:网络
someone already asked this question, but the thread ended up with the original question not getting answered.

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

精彩评论

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