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

Gle*_*enn 8 c++ syntax templates operator-overloading operators

有人已经问过这个问题了,但是线程结束时原来的问题没有得到回答.

假设你有这个:

template<size_t i, class f_type>
void call_with_i(f_type f);
Run Code Online (Sandbox Code Playgroud)

functor_type是:

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

template<size_t i> operator()() const;
Run Code Online (Sandbox Code Playgroud)

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

template<size_t i> foo();
Run Code Online (Sandbox Code Playgroud)

我希望"call_with_i <42>(foo)"等同于"foo <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. 
Run Code Online (Sandbox Code Playgroud)

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

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

编辑注释:我删除了东西,因为将模板化的自由函数作为arg传递没有任何意义.

Joh*_*itb 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>();
}
Run Code Online (Sandbox Code Playgroud)

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

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>());
}
Run Code Online (Sandbox Code Playgroud)

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

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

这对于模板化的构造函数来说很方便,你不能做什么f_type()<i>()或什么的.在这种情况下,他们必须是可以扣除的.