函数对象的正确参数类型是什么?
What is the correct argument type for a function-object?
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 程序员熟悉被复制的函数,因此,如果您做标准库所做的事情,那么通常您不会使他们的生活更糟。除非您将函数复制不是问题: - )
- 标准 N3337 5.2.10 第 7 条中的C++"类型"是什么意思?
- 如何声明一个标准::提升直方图的向量?提升直方图的类型是什么?
- 类名后跟括号的类型是什么
- std::chrono::duration::count函数的实际结果类型是什么
- c++运算符重载-我实际返回的操作数类型是什么
- 运算符和返回类型是什么意思?
- 指向 2D 数组的指针的类型是什么?
- RSA_verify中预期的数据类型是什么,无法验证从 Java 生成的签名
- 共享_ptr中多功能数组的类型是什么
- 构造函数的类型是什么?
- 字符串中单个字符作为数组的数据类型是什么
- 该结构继承的类型是什么
- 如果我获得Integer和Double的产品,输出的数据类型是什么
- C 中被视为可可的类型是什么
- 当函数采用右值引用时,函数中该变量的类型是什么?
- STD :: SETW,STD :: SETFILL等的真实返回类型是什么?
- 模板类中引用的引用的类型是什么
- const自动参考绑定到(NULL)指针 - 实际类型是什么
- 包含通过引用捕获的 lambda 函数的"variable"的类型是什么?
- 通过插座发送的内容的数据类型是什么