2009-11-19 75 views
7

有人已经问过这个问题,但是线程结束时原始问题没有得到解答。模板化运算符()重载C++

假设你有这样的:

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

functor_type可以是:

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

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

或b)一个看起来像这样的功能:

template<size_t i> foo(); 

我想“call_with_i < 42>(富)”等效于“富< 42>()”,但我不能找出正确的语法来做到这一点。 (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调用f(0)然后调用f(1)... f(10)。我使用它通过索引并行地遍历多个boost :: fusion向量。是的,我可以使用迭代器,或者我可以使用一个命名成员函数,但我仍然想知道答案。

编辑说明:我剔除了东西,因为传递一个模板化的自由函数作为参数并没有任何意义。

+0

它没有得到回答,因为你不能。 – GManNickG 2009-11-19 09:46:31

回答

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. 
} 

这都得心应手模板的构造函数,用W你不能这样做f_type()<i>()什么的。在这种情况下,他们将可以被扣除。

+0

@Johannes:为什么不专注于使用SFINAE的功能? – 2009-11-19 09:57:44

+0

很棒!非常棒。你是我的元英雄。 啊,而你使用mpl :: int_的想法也很聪明。 – Glenn 2009-11-19 09:59:01

+0

@ laulaulabs.mp,很高兴能有帮助:) – 2009-11-19 10:18:28

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

有没有一种方法来调用它的方式,相同的语法也将调用模板免费功能?

你能澄清吗? (伪代码,或者其他)

+0

实际上,我关于模板化自由函数的一点是无稽之谈,因为你无法将函数模板作为参数传递。 – Glenn 2009-11-19 10:04:44

1

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