模板化的operator()重载C ++

时间:2009-11-19 09:37:27

标签: c++ templates syntax operators operator-overloading

有人已经问了这个问题,但最终问题没有得到回答。

假设你有这个:

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

functor_type是:

a)具有以下签名的方法的结构:

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

<击>  或者,b)看起来像这样的函数:

template<size_t i> foo();

<击>

我希望“call_with_i&lt; 42&gt;(foo)”等同于“foo&lt; 42&gt;()”,但我无法找到正确的语法来实现这一点。我会满足于只做(a)的解决方案但是(a)+(b)会很棒。我已经尝试过这些语法:

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. 

如何使用显式模板参数调用operator()? 有没有办法以同样的语法也可以调用模板化自由函数的方式调用它?

P.S。如果你想知道我用它是什么,那是因为我正在写一个函数repeat_to,其中repeat_to&lt; 10&gt;(f)调用f(0)然后调用f(1)... f(10)。我正在使用它通过索引并行迭代多个boost :: fusion向量。是的,我可以使用迭代器,或者我可以使用命名成员函数,但我仍然想知道答案。

编辑注释:我删除了一些内容,因为将模板化的自由函数作为arg传递没有任何意义。

3 个答案:

答案 0 :(得分:13)

成员模板是从属名称,因为它的语义取决于f_type的类型。这意味着您应该在其名称前放置“模板”(以消除“少于”令牌的使用歧义),类似于您应该在依赖的限定名称之前放置typename

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

作为解决方法,您可以使用帮助程序类型:

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>());
}

现在,您可以按如下方式定义operator()

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

对于模板化构造函数来说,这很方便,你不能做f_type()<i>()或其他东西。在这种情况下,他们 可以扣除。

答案 1 :(得分:1)

在像你这样的情况下,我会使用boost :: function作为函子类型。然后,您可以传递函数对象和函数指针,同时保留相同的接口。

答案 2 :(得分:0)

#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;
}
  

有没有办法以同样的语法也可以调用模板化自由函数的方式调用它?

你能澄清一下吗? (伪代码或其他东西)