函数对象的正确参数类型是什么?

What is the correct argument type for a function-object?

本文关键字:类型 是什么 参数 对象 函数      更新时间:2023-10-16

i具有接收函数对象的模板函数。有时函数对象是无状态结构,但有时它们是大型状态对象。仅在此功能中检查,函数对象的状态没有更改。我也非常热衷于编写编译器可以尽可能优化编译器。选择参数类型时我应该考虑什么?

该功能是这种类型的:

template<typename funcT>
auto make_particle(funcT fun) {
   Particle<typename funcT::result_type> particle;
   particle = fun();
   return particle;
}

参数类型可能应该是funcT const & fun,以便不复制大型对象,但是为什么大多数人都使用逐个价值函数对象?我会使用const参考而使某些东西放松吗?还是我应该使用lvalue-renference?请注意,C 1Y还可以,上面的代码示例只是一个示例。

有几种用例,都应可用:

  • 函子没有状态,并作为临时性提供:make_particle(MyFun())

  • 函子具有稍后需要恢复的状态: YourFun f; make_particle(f);

您无法使用一个单个参考类型参数解决这两种情况:第一种情况需要const lVALUE参考或RVALUE参考,该参考禁止第二种使用,第二种情况下,第二种情况是禁止的lVALUE参考,该参考禁止首次使用。<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

在这种情况下,一个常见的成语是按值接受函子,在结尾处返回:

template <typename Iter, typename F>
F map(Iter first, Iter last, F f)
{
    // ... f(*first) ...
    return f;
}

,这可能并不完全适用于您的情况,但这是一个主意。例如,您可以返回std::pair<ParticleType, F>。无论如何,您都需要复制函子类型,但这是合理的要求。

另一种由@xeo指出的替代方案,仅用于函数 templates ,是通过Universal参数进行函数参数,在两种情况下都可以使用:

template <typename Iter, typename F>
void map(Iter first, Iter last, F && f)
{
    // ... use f(*first) ...
}

请注意,在这种情况下,我们使用std::forward,因为我们使用f作为真正的参考,而不仅仅是将其通过其他地方。特别是,如果我们仍然打算使用它,则不允许从f移动。

参数类型可能应函数const&amp;有趣的是 大型物体未复制,

这不是标准库中算法所采用的视图。在那里,可呼叫的对象是按值采用的。这取决于可呼叫对象的作者,以确保复制合理 。例如,如果它需要访问大型东西,则可以让函数的用户提供对一个的参考并存储在函数中 - 复制参考很便宜。

现在,您可能想对标准库的做事有所不同,因为您期望粒子制造功能变得廉价地复制或移动非常困难。但是C 程序员熟悉被复制的函数,因此,如果您做标准库所做的事情,那么通常您不会使他们的生活更糟。除非您将函数复制不是问题: - )