faq.xml 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!--
  3. Copyright (c) 2002 Douglas Gregor <doug.gregor -at- gmail.com>
  4. Distributed under the Boost Software License, Version 1.0.
  5. (See accompanying file LICENSE_1_0.txt or copy at
  6. http://www.boost.org/LICENSE_1_0.txt)
  7. -->
  8. <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
  9. "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
  10. <section id="function.faq" last-revision="$Date$">
  11. <title>Frequently Asked Questions</title>
  12. <qandaset>
  13. <qandaentry>
  14. <question><para>Why can't I compare
  15. <classname>boost::function</classname> objects with
  16. <code>operator==</code> or
  17. <code>operator!=</code>?</para></question>
  18. <answer>
  19. <para>Comparison between <classname>boost::function</classname>
  20. objects cannot be implemented "well", and therefore will not be
  21. implemented. The typical semantics requested for <code>f ==
  22. g</code> given <classname>boost::function</classname> objects
  23. <code>f</code> and <code>g</code> are:</para>
  24. <itemizedlist>
  25. <listitem><simpara>If <code>f</code> and <code>g</code>
  26. store function objects of the same type, use that type's
  27. <code>operator==</code> to compare
  28. them.</simpara></listitem>
  29. <listitem><simpara>If <code>f</code> and <code>g</code>
  30. store function objects of different types, return
  31. <code>false</code>.</simpara></listitem>
  32. </itemizedlist>
  33. <para>The problem occurs when the type of the function objects
  34. stored by both <code>f</code> and <code>g</code> doesn't have an
  35. <code>operator==</code>: we would like the expression <code>f ==
  36. g</code> to fail to compile, as occurs with, e.g., the standard
  37. containers. However, this is not implementable for
  38. <classname>boost::function</classname> because it necessarily
  39. "erases" some type information after it has been assigned a
  40. function object, so it cannot try to call
  41. <code>operator==</code> later: it must either find a way to call
  42. <code>operator==</code> now, or it will never be able to call it
  43. later. Note, for instance, what happens if you try to put a
  44. <code>float</code> value into a
  45. <classname>boost::function</classname> object: you will get an
  46. error at the assignment operator or constructor, not in
  47. <code>operator()</code>, because the function-call expression
  48. must be bound in the constructor or assignment operator.</para>
  49. <para>The most promising approach is to find a method of
  50. determining if <code>operator==</code> can be called for a
  51. particular type, and then supporting it only when it is
  52. available; in other situations, an exception would be
  53. thrown. However, to date there is no known way to detect if an
  54. arbitrary operator expression <code>f == g</code> is suitably
  55. defined. The best solution known has the following undesirable
  56. qualities:</para>
  57. <orderedlist>
  58. <listitem><simpara>Fails at compile-time for objects where
  59. <code>operator==</code> is not accessible (e.g., because it is
  60. <code>private</code>).</simpara></listitem>
  61. <listitem><simpara>Fails at compile-time if calling
  62. <code>operator==</code> is ambiguous.</simpara></listitem>
  63. <listitem><simpara>Appears to be correct if the
  64. <code>operator==</code> declaration is correct, even though
  65. <code>operator==</code> may not compile.</simpara></listitem>
  66. </orderedlist>
  67. <para>All of these problems translate into failures in the
  68. <classname>boost::function</classname> constructors or
  69. assignment operator, <emphasis>even if the user never invokes
  70. operator==</emphasis>. We can't do that to users.</para>
  71. <para>The other option is to place the burden on users that want
  72. to use <code>operator==</code>, e.g., by providing an
  73. <code>is_equality_comparable</code> trait they may
  74. specialize. This is a workable solution, but is dangerous in
  75. practice, because forgetting to specialize the trait will result
  76. in unexpected exceptions being thrown from
  77. <classname>boost::function</classname>'s
  78. <code>operator==</code>. This essentially negates the usefulness
  79. of <code>operator==</code> in the context in which it is most
  80. desired: multitarget callbacks. The
  81. <libraryname>Signals</libraryname> library has a way around
  82. this.</para>
  83. </answer>
  84. </qandaentry>
  85. <qandaentry>
  86. <question><para>I see void pointers; is this [mess] type safe?</para></question>
  87. <answer>
  88. <para>Yes, <computeroutput>boost::function</computeroutput> is type
  89. safe even though it uses void pointers and pointers to functions
  90. returning void and taking no arguments. Essentially, all type
  91. information is encoded in the functions that manage and invoke
  92. function pointers and function objects. Only these functions are
  93. instantiated with the exact type that is pointed to by the void
  94. pointer or pointer to void function. The reason that both are required
  95. is that one may cast between void pointers and object pointers safely
  96. or between different types of function pointers (provided you don't
  97. invoke a function pointer with the wrong type). </para>
  98. </answer>
  99. </qandaentry>
  100. <qandaentry>
  101. <question><para>Why are there workarounds for void returns? C++ allows them!</para></question>
  102. <answer><para>Void returns are permitted by the C++ standard, as in this code snippet:
  103. <programlisting>void f();
  104. void g() { return f(); }</programlisting>
  105. </para>
  106. <para> This is a valid usage of <computeroutput>boost::function</computeroutput> because void returns are not used. With void returns, we would attempting to compile ill-formed code similar to:
  107. <programlisting>int f();
  108. void g() { return f(); }</programlisting>
  109. </para>
  110. <para> In essence, not using void returns allows
  111. <computeroutput>boost::function</computeroutput> to swallow a return value. This is
  112. consistent with allowing the user to assign and invoke functions and
  113. function objects with parameters that don't exactly match.</para>
  114. </answer>
  115. </qandaentry>
  116. <qandaentry>
  117. <question><para>Why (function) cloning?</para></question>
  118. <answer>
  119. <para>In November and December of 2000, the issue of cloning
  120. vs. reference counting was debated at length and it was decided
  121. that cloning gave more predictable semantics. I won't rehash the
  122. discussion here, but if it cloning is incorrect for a particular
  123. application a reference-counting allocator could be used.</para>
  124. </answer>
  125. </qandaentry>
  126. <qandaentry>
  127. <question><para>How much overhead does a call through <code><classname>boost::function</classname></code> incur?</para></question>
  128. <answer>
  129. <para>The cost of <code>boost::function</code> can be reasonably
  130. consistently measured at around 20ns +/- 10 ns on a modern >2GHz
  131. platform versus directly inlining the code.</para>
  132. <para>However, the performance of your application may benefit
  133. from or be disadvantaged by <code>boost::function</code>
  134. depending on how your C++ optimiser optimises. Similar to a
  135. standard function pointer, differences of order of 10% have been
  136. noted to the benefit or disadvantage of using
  137. <code>boost::function</code> to call a function that contains a
  138. tight loop depending on your compilation circumstances.</para>
  139. <para>[Answer provided by Matt Hurd. See <ulink url="http://article.gmane.org/gmane.comp.lib.boost.devel/33278"/>]</para>
  140. </answer>
  141. </qandaentry>
  142. </qandaset>
  143. </section>