我刚才所读经典书“有效的C++,第3版”,并在第20项笔者的结论是,内置类型,STL的迭代器和函数对象种类较多,适合传递价值。我可以很好理解内建和迭代器类型的原因,但为什么要函数对象被传递由值,因为我们知道这是无论如何类类型?为什么函数对象应该是通过按值
回答
在典型的情况下,一个功能对象将有很少或(更通常)没有持久状态。在这种情况下,通过价值传递可能不需要实际传递任何东西 - 传递的“价值”基本上只是“这是对象”的占位符。
由于许多函数对象中的代码量很少,导致进一步优化:编译器通常很容易扩展函数对象的内联代码,因此没有参数传递,并且没有函数调用参与其中。
编译器可以能够当你通过指针或引用,而不是做同样的,但它不是那么容易 - 很多比较常见的,你会与对象最终被创建的,其地址传递,然后通过该指针调用该对象的函数调用操作符。
编辑:这可能也是值得一提的是,同样适用于lambda表达式,因为他们真的只是功能伪装对象。你不知道类的名字,但是他们在紧邻的作用域中创建一个类,它重载了函数调用操作符,当你“调用”lambda时被调用。 [感谢@马克西亚。]
感谢您的解释,“内联优化”部分让我印象深刻。 – JavaBeta
我的工作经验表明,广泛使用'boost :: bind'会导致复制的代价很高的函数对象。这似乎成倍增加绑定深度(结合具有结合内部等回调回调) –
从有效的STL(因为你看起来很喜欢斯科特·迈耶斯)第38项设计仿函数类用于传递值。
“在C和C++中,函数指针都是按值传递的,STL函数对象是在函数指针之后建模的,所以STL中的约定是,函数对象也是在函数传递时通过值传递的。 “编辑器可以做一些优化,比如内联代码以避免函数调用(你必须将你的函数标记为内联),这有一些好处和一些暗示,像@Jerry Coffin说的。这种情况的一个很好的例子是qsort vs std :: sort性能比较,其中std :: sort使用内联函数的性能比qsort大很多,你可以在有效的STL中找到更多关于这方面的信息,这在广泛讨论并在几个章节。
这也有一些暗示,因为函数对象是通过值并返回的,所以您必须确保您的对象具有定义良好的复制机制,体积小(否则可能会变得昂贵),并且是单形的(因为按值传递多态对象可能会导致对象切片)。
迈尔斯的有效串联是在中国很受欢迎:-)。另外,感谢std :: sort和std :: qsort之间的区别。 – JavaBeta
#1原因按值传递函数对象是因为标准库需要函数对象传递给它的算法,可拷贝。 C++ 11§25.1/ 10:
[注:除非另有规定,即采取函数对象作为参数被允许的算法复制 那些功能自由对象。对他们来说,程序员对象的身份是很重要的应该考虑使用一个指向noncopied实施对象,如
reference_wrapper<T>
(20.8.3), 或某些等效解决方案 包装类。 - 注意]
其他答案做了很好的解释理由。
- 1. 模型和数据访问对象,应该通过,应该通过什么
- 2. 为什么我们应该总是从函数返回值?
- 3. 为什么我应该模拟对象?
- 4. 实体,价值对象还是它应该是什么?
- 5. 什么应该是构造函数属性值..a原型构造函数或对象构造函数本身
- 6. 按前缀过滤数组 - 该函数的名称是什么?
- 7. 为什么按值传递一个对象即使该对象没有拷贝构造函数也能工作?
- 8. 通过函数访问对象值
- 9. 对象值通过C++函数
- 10. 原生$函数应该是什么?
- 11. dummy()函数 - 这应该是什么?
- 12. 为什么mvc无法通过对象
- 13. Perl:“validate”函数中类对象应该使用什么类型
- 14. 为什么cppcheck说“函数参数应该通过引用传递”?
- 15. 通过对象不是值
- 16. 应该是什么,我可以在XML通过除X为CHECKBOXTYPE
- 17. 什么行为应该是测试的对象?
- 18. lambda函数C++通过值捕获重置其值,为什么?
- 19. 什么是对象构造函数?
- 20. 为什么对象类不是空值
- 21. 为什么我们无法通过jquery获取对象值
- 22. 为什么数组的对象属性正确访问该值?
- 23. 为什么我们应该在全局函数/对象上使用“::”运算符?
- 24. javascript如果函数是对象,那么为什么不工作
- 25. 从函数返回大对象:通过值VS通过指针
- 26. 我应该通过什么作为参数?
- 27. 什么时候应该通过一个类作为参数?
- 28. 从函数中通过引用获取对象,而不是值
- 29. C++为什么变量是函数而不是对象?
- 30. 为什么Math是一个对象而String是一个函数?
+1看了C++有效 – Borgleader
函数对象应该很少有多大的开销。 – chris
至少,现在有更多的逻辑(所有对象,一般)都有移动语义。 –