2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-23 17:52:17 +00:00

Tutorial updates. Added virtual functions with default implementations and reshufled the overloading topics to discuss manual overloading first.

[SVN r17597]
This commit is contained in:
Joel de Guzman
2003-02-23 02:23:15 +00:00
parent acdad5caf3
commit 2a530bb9d2
11 changed files with 447 additions and 264 deletions

View File

@@ -0,0 +1,112 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Auto-Overloading</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="default_arguments.html">
<link rel="next" href="object_interface.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Auto-Overloading</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="default_arguments.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="object_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
It was mentioned in passing in the previous section that
<tt>BOOST_PYTHON_FUNCTION_OVERLOADS</tt> and <tt>BOOST_PYTHON_FUNCTION_OVERLOADS</tt>
can also be used for overloaded functions and member functions with a
common sequence of initial arguments. Here is an example:</p>
<code><pre>
<span class=keyword>void </span><span class=identifier>foo</span><span class=special>()
{
/*...*/
}
</span><span class=keyword>void </span><span class=identifier>foo</span><span class=special>(</span><span class=keyword>bool </span><span class=identifier>a</span><span class=special>)
{
/*...*/
}
</span><span class=keyword>void </span><span class=identifier>foo</span><span class=special>(</span><span class=keyword>bool </span><span class=identifier>a</span><span class=special>, </span><span class=keyword>int </span><span class=identifier>b</span><span class=special>)
{
/*...*/
}
</span><span class=keyword>void </span><span class=identifier>foo</span><span class=special>(</span><span class=keyword>bool </span><span class=identifier>a</span><span class=special>, </span><span class=keyword>int </span><span class=identifier>b</span><span class=special>, </span><span class=keyword>char </span><span class=identifier>c</span><span class=special>)
{
/*...*/
}
</span></pre></code>
<p>
Like in the previous section, we can generate thin wrappers for these
overloaded functions in one-shot:</p>
<code><pre>
<span class=identifier>BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class=special>(</span><span class=identifier>foo_overloads</span><span class=special>, </span><span class=identifier>foo</span><span class=special>, </span><span class=number>0</span><span class=special>, </span><span class=number>3</span><span class=special>)
</span></pre></code>
<p>
Then...</p>
<code><pre>
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;foo&quot;</span><span class=special>, </span><span class=identifier>foo</span><span class=special>, </span><span class=identifier>foo_overloads</span><span class=special>());
</span></pre></code>
<p>
Notice though that we have a situation now where we have a minimum of zero
(0) arguments and a maximum of 3 arguments.</p>
<a name="manual_wrapping"></a><h2>Manual Wrapping</h2><p>
It is important to emphasize however that <b>the overloaded functions must
have a common sequence of initial arguments</b>. Otherwise, our scheme above
will not work. If this is not the case, we have to wrap our functions
<a href="overloading.html">
manually</a>.</p>
<p>
Actually, we can mix and match manual wrapping of overloaded functions and
automatic wrapping through <tt>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt> and
its sister, <tt>BOOST_PYTHON_FUNCTION_OVERLOADS</tt>. Following up on our example
presented in the section <a href="overloading.html">
on overloading</a>, since the
first overload has default arguments, we can use
<tt>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt> to automatically wrap the first
three of the <tt>def</tt>s above and manually wrap just the last. Here's how
we'll do this:</p>
<code><pre>
<span class=identifier>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class=special>(</span><span class=identifier>xf_overloads</span><span class=special>, </span><span class=identifier>f</span><span class=special>, </span><span class=number>1</span><span class=special>, </span><span class=number>4</span><span class=special>)
</span></pre></code>
<p>
Create a member function pointers as above for both X::f overloads:</p>
<code><pre>
<span class=keyword>bool </span><span class=special>(</span><span class=identifier>X</span><span class=special>::*</span><span class=identifier>fx1</span><span class=special>)(</span><span class=keyword>int</span><span class=special>, </span><span class=keyword>double</span><span class=special>, </span><span class=keyword>char</span><span class=special>) = &amp;</span><span class=identifier>X</span><span class=special>::</span><span class=identifier>f</span><span class=special>;
</span><span class=keyword>int </span><span class=special>(</span><span class=identifier>X</span><span class=special>::*</span><span class=identifier>fx2</span><span class=special>)(</span><span class=keyword>int</span><span class=special>, </span><span class=keyword>int</span><span class=special>, </span><span class=keyword>int</span><span class=special>) = &amp;</span><span class=identifier>X</span><span class=special>::</span><span class=identifier>f</span><span class=special>;
</span></pre></code>
<p>
Then...</p>
<code><pre>
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>fx1</span><span class=special>, </span><span class=identifier>xf_overloads</span><span class=special>());
.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>fx2</span><span class=special>)
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="default_arguments.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="object_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -4,7 +4,7 @@
<title>Call Policies</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="functions.html">
<link rel="next" href="default_arguments.html">
<link rel="next" href="overloading.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
@@ -21,7 +21,7 @@
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="default_arguments.html"><img src="theme/r_arr.gif" border="0"></a></td>
<td width="20"><a href="overloading.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
@@ -156,7 +156,7 @@ here</a>.</p>
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="default_arguments.html"><img src="theme/r_arr.gif" border="0"></a></td>
<td width="20"><a href="overloading.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>

View File

@@ -3,7 +3,7 @@
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Class Operators/Special Functions</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="class_virtual_functions.html">
<link rel="prev" href="virtual_functions_with_default_implementations.html">
<link rel="next" href="functions.html">
</head>
<body>
@@ -20,7 +20,7 @@
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_virtual_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="30"><a href="virtual_functions_with_default_implementations.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
@@ -95,7 +95,7 @@ Well, the method <tt>str</tt> requires the <tt>operator&lt;&lt;</tt> to do its w
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_virtual_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="30"><a href="virtual_functions_with_default_implementations.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>

View File

@@ -4,7 +4,7 @@
<title>Class Virtual Functions</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="inheritance.html">
<link rel="next" href="class_operators_special_functions.html">
<link rel="next" href="deriving_a_python_class.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
@@ -21,7 +21,7 @@
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="inheritance.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="class_operators_special_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
<td width="20"><a href="deriving_a_python_class.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
@@ -112,118 +112,11 @@ In Python, let us try to instantiate our <tt>Base</tt> class:</p>
Why is it an error? <tt>Base</tt> is an abstract class. As such it is advisable
to define the Python wrapper with <tt>no_init</tt> as we have done above. Doing
so will disallow abstract base classes such as <tt>Base</tt> to be instantiated.</p>
<a name="deriving_a_python_class"></a><h2>Deriving a Python class</h2><p>
Now, at last, we can even derive from our base class Base in Python. Before
we can do that, we have to set up our class_ wrapper as:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Base</span><span class=special>, </span><span class=identifier>BaseWrap</span><span class=special>, </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>noncopyable</span><span class=special>&gt;(</span><span class=string>&quot;Base&quot;</span><span class=special>)
;
</span></pre></code>
<p>
Otherwise, we have to suppress the Base class' <tt>no_init</tt> by adding an
<tt>__init__()</tt> method to all our derived classes. <tt>no_init</tt> actually adds
an <tt>__init__</tt> method that raises a Python RuntimeError exception.</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=keyword>class </span><span class=identifier>Derived</span><span class=special>(</span><span class=identifier>Base</span><span class=special>):
... </span><span class=identifier>def </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
... </span><span class=keyword>return </span><span class=number>42
</span><span class=special>...
</span></pre></code>
<p>
Cool eh? A Python class deriving from a C++ class!</p>
<p>
Let's now make an instance of our Python class <tt>Derived</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>derived </span><span class=special>= </span><span class=identifier>Derived</span><span class=special>()
</span></pre></code>
<p>
Calling <tt>derived.f()</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>derived</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
</span><span class=number>42
</span></pre></code>
<p>
Will yield the expected result. Finally, calling calling the free function
<tt>call_f</tt> with <tt>derived</tt> as argument:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>derived</span><span class=special>)
</span><span class=number>42
</span></pre></code>
<p>
Will also yield the expected result.</p>
<p>
Here's what's happening:</p>
<ol><li><tt>call_f(derived)</tt> is called in Python</li><li>This corresponds to <tt>def(&quot;call_f&quot;, call_f);</tt>. Boost.Python dispatches this call.</li><li><tt>int call_f(Base&amp; b) { return b.f(); }</tt> accepts the call.</li><li>The overridden virtual function <tt>f</tt> of <tt>BaseWrap</tt> is called.</li><li><tt>call_method&lt;int&gt;(self, &quot;f&quot;);</tt> dispatches the call back to Python.</li><li><tt>def f(self): return 42</tt> is finally called.</li></ol><p>
Rewind back to our <tt>Base</tt> class, if its member function <tt>f</tt> was not
declared as pure virtual:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>Base
</span><span class=special>{
</span><span class=keyword>virtual </span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() { </span><span class=keyword>return </span><span class=number>0</span><span class=special>; }
};
</span></pre></code>
<p>
And instead is implemented to return <tt>0</tt>, as shown above.</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>BaseWrap </span><span class=special>: </span><span class=identifier>Base
</span><span class=special>{
</span><span class=identifier>BaseWrap</span><span class=special>(</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self_</span><span class=special>)
: </span><span class=identifier>self</span><span class=special>(</span><span class=identifier>self_</span><span class=special>) {}
</span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() { </span><span class=keyword>return </span><span class=identifier>call_method</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;(</span><span class=identifier>self</span><span class=special>, </span><span class=string>&quot;f&quot;</span><span class=special>); }
</span><span class=keyword>static </span><span class=keyword>int </span><span class=identifier>default_f</span><span class=special>(</span><span class=identifier>Base</span><span class=special>* </span><span class=identifier>b</span><span class=special>) { </span><span class=keyword>return </span><span class=identifier>b</span><span class=special>-&gt;</span><span class=identifier>Base</span><span class=special>::</span><span class=identifier>f</span><span class=special>(); } // &lt;&lt;=== </span><span class=identifier>added
</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self</span><span class=special>;
};
</span></pre></code>
<p>
then, our Boost.Python wrapper:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Base</span><span class=special>, </span><span class=identifier>BaseWrap</span><span class=special>&gt;(</span><span class=string>&quot;Base&quot;</span><span class=special>)
.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, &amp;</span><span class=identifier>BaseWrap</span><span class=special>::</span><span class=identifier>default_f</span><span class=special>)
;
</span></pre></code>
<p>
Note that we are allowing <tt>Base</tt> objects to be instantiated this time,
unlike before where we specifically defined the <tt>class_&lt;Base&gt;</tt> with
<tt>no_init</tt>.</p>
<p>
In Python, the results would be as expected:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>base </span><span class=special>= </span><span class=identifier>Base</span><span class=special>()
&gt;&gt;&gt; </span><span class=keyword>class </span><span class=identifier>Derived</span><span class=special>(</span><span class=identifier>Base</span><span class=special>):
... </span><span class=identifier>def </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
... </span><span class=keyword>return </span><span class=number>42
</span><span class=special>...
&gt;&gt;&gt; </span><span class=identifier>derived </span><span class=special>= </span><span class=identifier>Derived</span><span class=special>()
</span></pre></code>
<p>
Calling <tt>base.f()</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>base</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
</span><span class=number>0
</span></pre></code>
<p>
Calling <tt>derived.f()</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>derived</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
</span><span class=number>42
</span></pre></code>
<p>
Calling <tt>call_f</tt>, passing in a <tt>base</tt> object:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>base</span><span class=special>)
</span><span class=number>0
</span></pre></code>
<p>
Calling <tt>call_f</tt>, passing in a <tt>derived</tt> object:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>derived</span><span class=special>)
</span><span class=number>42
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="inheritance.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="class_operators_special_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
<td width="20"><a href="deriving_a_python_class.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>

View File

@@ -3,8 +3,8 @@
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Default Arguments</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="call_policies.html">
<link rel="next" href="overloading.html">
<link rel="prev" href="overloading.html">
<link rel="next" href="auto_overloading.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
@@ -20,8 +20,8 @@
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="call_policies.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="overloading.html"><img src="theme/r_arr.gif" border="0"></a></td>
<td width="30"><a href="overloading.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="auto_overloading.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
@@ -44,8 +44,10 @@ to retrieve the default arguments:</p>
<span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>f</span><span class=special>); // </span><span class=identifier>defaults </span><span class=identifier>lost</span><span class=special>!
</span></pre></code>
<p>
Because of this, when wrapping C++ code in earlier versions of
Boost.Python, we had to resort to writing thin wrappers:</p>
Because of this, when wrapping C++ code, we had to resort to manual
wrapping as outlined in the <a href="overloading.html">
previous section</a>, or
writing thin wrappers:</p>
<code><pre>
<span class=comment>// write &quot;thin wrappers&quot;
</span><span class=keyword>int </span><span class=identifier>f1</span><span class=special>(</span><span class=keyword>int </span><span class=identifier>x</span><span class=special>) { </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>x</span><span class=special>); }
@@ -142,8 +144,8 @@ Notice the use of <tt>init&lt;...&gt;</tt> and <tt>optional&lt;...&gt;</tt> to s
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="call_policies.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="overloading.html"><img src="theme/r_arr.gif" border="0"></a></td>
<td width="30"><a href="overloading.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="auto_overloading.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>

View File

@@ -0,0 +1,82 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Deriving a Python Class</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="class_virtual_functions.html">
<link rel="next" href="virtual_functions_with_default_implementations.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Deriving a Python Class</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_virtual_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="virtual_functions_with_default_implementations.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Continuing, now, at last, we can even derive from our base class Base in
Python. Before we can do that, we have to set up our <tt>class_</tt> wrapper as:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Base</span><span class=special>, </span><span class=identifier>BaseWrap</span><span class=special>, </span><span class=identifier>boost</span><span class=special>::</span><span class=identifier>noncopyable</span><span class=special>&gt;(</span><span class=string>&quot;Base&quot;</span><span class=special>)
;
</span></pre></code>
<p>
Otherwise, we have to suppress the Base class' <tt>no_init</tt> by adding an
<tt>__init__()</tt> method to all our derived classes. <tt>no_init</tt> actually adds
an <tt>__init__</tt> method that raises a Python RuntimeError exception.</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=keyword>class </span><span class=identifier>Derived</span><span class=special>(</span><span class=identifier>Base</span><span class=special>):
... </span><span class=identifier>def </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
... </span><span class=keyword>return </span><span class=number>42
</span><span class=special>...
</span></pre></code>
<p>
Cool eh? A Python class deriving from a C++ class!</p>
<p>
Let's now make an instance of our Python class <tt>Derived</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>derived </span><span class=special>= </span><span class=identifier>Derived</span><span class=special>()
</span></pre></code>
<p>
Calling <tt>derived.f()</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>derived</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
</span><span class=number>42
</span></pre></code>
<p>
Will yield the expected result. Finally, calling calling the free function
<tt>call_f</tt> with <tt>derived</tt> as argument:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>derived</span><span class=special>)
</span><span class=number>42
</span></pre></code>
<p>
Will also yield the expected result.</p>
<p>
Here's what's happening:</p>
<ol><li><tt>call_f(derived)</tt> is called in Python</li><li>This corresponds to <tt>def(&quot;call_f&quot;, call_f);</tt>. Boost.Python dispatches this call.</li><li><tt>int call_f(Base&amp; b) { return b.f(); }</tt> accepts the call.</li><li>The overridden virtual function <tt>f</tt> of <tt>BaseWrap</tt> is called.</li><li><tt>call_method&lt;int&gt;(self, &quot;f&quot;);</tt> dispatches the call back to Python.</li><li><tt>def f(self): return 42</tt> is finally called.</li></ol><table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="class_virtual_functions.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="virtual_functions_with_default_implementations.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -3,7 +3,7 @@
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Object Interface</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="overloading.html">
<link rel="prev" href="auto_overloading.html">
<link rel="next" href="basic_interface.html">
</head>
<body>
@@ -20,7 +20,7 @@
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="overloading.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="30"><a href="auto_overloading.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="basic_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
@@ -40,7 +40,7 @@ should minimize the learning curve significantly.</p>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="overloading.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="30"><a href="auto_overloading.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="basic_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>

View File

@@ -3,8 +3,8 @@
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Overloading</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="default_arguments.html">
<link rel="next" href="object_interface.html">
<link rel="prev" href="call_policies.html">
<link rel="next" href="default_arguments.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
@@ -20,59 +20,16 @@
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="default_arguments.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="object_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
<td width="30"><a href="call_policies.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="default_arguments.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
It was mentioned in passing in the previous section that
<tt>BOOST_PYTHON_FUNCTION_OVERLOADS</tt> and <tt>BOOST_PYTHON_FUNCTION_OVERLOADS</tt>
can also be used for overloaded functions and member functions with a
common sequence of initial arguments. Here is an example:</p>
<code><pre>
<span class=keyword>void </span><span class=identifier>foo</span><span class=special>()
{
/*...*/
}
</span><span class=keyword>void </span><span class=identifier>foo</span><span class=special>(</span><span class=keyword>bool </span><span class=identifier>a</span><span class=special>)
{
/*...*/
}
</span><span class=keyword>void </span><span class=identifier>foo</span><span class=special>(</span><span class=keyword>bool </span><span class=identifier>a</span><span class=special>, </span><span class=keyword>int </span><span class=identifier>b</span><span class=special>)
{
/*...*/
}
</span><span class=keyword>void </span><span class=identifier>foo</span><span class=special>(</span><span class=keyword>bool </span><span class=identifier>a</span><span class=special>, </span><span class=keyword>int </span><span class=identifier>b</span><span class=special>, </span><span class=keyword>char </span><span class=identifier>c</span><span class=special>)
{
/*...*/
}
</span></pre></code>
<p>
Like in the previous section, we can generate thin wrappers for these
overloaded functions in one-shot:</p>
<code><pre>
<span class=identifier>BOOST_PYTHON_FUNCTION_OVERLOADS</span><span class=special>(</span><span class=identifier>foo_overloads</span><span class=special>, </span><span class=identifier>foo</span><span class=special>, </span><span class=number>0</span><span class=special>, </span><span class=number>3</span><span class=special>)
</span></pre></code>
<p>
Then...</p>
<code><pre>
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;foo&quot;</span><span class=special>, </span><span class=identifier>foo</span><span class=special>, </span><span class=identifier>foo_overloads</span><span class=special>());
</span></pre></code>
<p>
Notice though that we have a situation now where we have a minimum of zero
(0) arguments and a maximum of 3 arguments.</p>
<a name="manual_wrapping"></a><h2>Manual Wrapping</h2><p>
It is important to emphasize however that <b>the overloaded functions must
have a common sequence of initial arguments</b>. Otherwise, our scheme above
will not work.</p>
<p>
The following illustrates an alternate scheme for manually wrapping an
overloaded member function instead of
<tt>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt>. Obviously, the same technique
can be applied to wrapping overloaded non- member functions.</p>
The following illustrates a scheme for manually wrapping an overloaded
member function or. Obviously, the same technique can be applied to
wrapping overloaded non- member functions. Take note that this scheme
applies to actual overloaded (member, non-member) functions as well as
(member, non-member) functions with default arguments.</p>
<p>
We have here our C++ classes:</p>
<code><pre>
@@ -113,33 +70,11 @@ With these in hand, we can proceed to define and wrap this for Python:</p>
.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>fx3</span><span class=special>)
.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>fx4</span><span class=special>)
</span></pre></code>
<p>
Actually, we can mix and match manual wrapping of overloaded functions and
automatic wrapping through <tt>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt> and
its sister, <tt>BOOST_PYTHON_FUNCTION_OVERLOADS</tt>. Since the first overload
has default arguments, we can use <tt>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</tt>
to automatically wrap the first three of the <tt>def</tt>s above and manually
wrap just the last. Here's how we'll do this:</p>
<code><pre>
<span class=identifier>BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS</span><span class=special>(</span><span class=identifier>xf_overloads</span><span class=special>, </span><span class=identifier>f</span><span class=special>, </span><span class=number>1</span><span class=special>, </span><span class=number>4</span><span class=special>)
</span></pre></code>
<p>
Create a member function pointers as above for both X::f overloads:</p>
<code><pre>
<span class=keyword>bool </span><span class=special>(</span><span class=identifier>X</span><span class=special>::*</span><span class=identifier>fx1</span><span class=special>)(</span><span class=keyword>int</span><span class=special>, </span><span class=keyword>double</span><span class=special>, </span><span class=keyword>char</span><span class=special>) = &amp;</span><span class=identifier>X</span><span class=special>::</span><span class=identifier>f</span><span class=special>;
</span><span class=keyword>int </span><span class=special>(</span><span class=identifier>X</span><span class=special>::*</span><span class=identifier>fx2</span><span class=special>)(</span><span class=keyword>int</span><span class=special>, </span><span class=keyword>int</span><span class=special>, </span><span class=keyword>int</span><span class=special>) = &amp;</span><span class=identifier>X</span><span class=special>::</span><span class=identifier>f</span><span class=special>;
</span></pre></code>
<p>
Then...</p>
<code><pre>
<span class=special>.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>fx1</span><span class=special>, </span><span class=identifier>xf_overloads</span><span class=special>());
.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, </span><span class=identifier>fx2</span><span class=special>)
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="default_arguments.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="object_interface.html"><img src="theme/r_arr.gif" border="0"></a></td>
<td width="30"><a href="call_policies.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="default_arguments.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>

View File

@@ -527,10 +527,10 @@ Why is it an error? [^Base] is an abstract class. As such it is advisable
to define the Python wrapper with [^no_init] as we have done above. Doing
so will disallow abstract base classes such as [^Base] to be instantiated.
[h2 Deriving a Python class]
[page:1 Deriving a Python Class]
Now, at last, we can even derive from our base class Base in Python. Before
we can do that, we have to set up our class_ wrapper as:
Continuing, now, at last, we can even derive from our base class Base in
Python. Before we can do that, we have to set up our [^class_] wrapper as:
class_<Base, BaseWrap, boost::noncopyable>("Base")
;
@@ -572,30 +572,45 @@ Here's what's happening:
# [^call_method<int>(self, "f");] dispatches the call back to Python.
# [^def f(self): return 42] is finally called.
Rewind back to our [^Base] class, if its member function [^f] was not
declared as pure virtual:
[page:1 Virtual Functions with Default Implementations]
Recall that in the [@class_virtual_functions.html previous section], we
wrapped a class with a pure virtual function that we then implemented in
C++ or Python classes derived from it. Our base class:
struct Base
{
virtual int f() = 0;
};
had a pure virtual function [^f]. If, however, its member function [^f] was
not declared as pure virtual:
struct Base
{
virtual int f() { return 0; }
};
And instead is implemented to return [^0], as shown above.
and instead had a default implementation that returns [^0], as shown above,
we need to add a forwarding function that calls the [^Base] default virtual
function [^f] implementation:
struct BaseWrap : Base
{
BaseWrap(PyObject* self_)
: self(self_) {}
int f() { return call_method<int>(self, "f"); }
static int default_f(Base* b) { return b->Base::f(); } // <<=== added
int default_f() { return Base::f(); } // <<=== ***ADDED***
PyObject* self;
};
then, our Boost.Python wrapper:
Then, Boost.Python needs to keep track of 1) the dispatch function [^f] and
2) the forwarding function to its default implementation [^default_f].
There's a special [^def] function for this purpose. Here's how it is
applied to our example above:
class_<Base, BaseWrap>("Base")
.def("f", &BaseWrap::default_f)
;
.def("f", &Base::f, &BaseWrap::default_f)
Note that we are allowing [^Base] objects to be instantiated this time,
unlike before where we specifically defined the [^class_<Base>] with
@@ -874,6 +889,51 @@ these can be found [@../../v2/reference.html#models_of_call_policies here].
"Explicit is better than implicit"[br]
"In the face of ambiguity, refuse the temptation to guess"[br]]
[page:1 Overloading]
The following illustrates a scheme for manually wrapping an overloaded
member function or. Obviously, the same technique can be applied to
wrapping overloaded non- member functions. Take note that this scheme
applies to actual overloaded (member, non-member) functions as well as
(member, non-member) functions with default arguments.
We have here our C++ classes:
struct X
{
bool f(int a, double b = 0, char c = 'x')
{
return true;
}
int f(int a, int b, int c)
{
return a + b + c;
};
};
Notice that class X has two overloaded functions with different signatures.
The types of the arguments, and the return are totally different, unlike
above where we have a common sequence of initial arguments.
We shall start by introducing some member function pointer variables:
bool (X::*fx1)(int) = &X::f;
bool (X::*fx2)(int, double) = &X::f;
bool (X::*fx3)(int, double, char)= &X::f;
int (X::*fx4)(int, int, int) = &X::f;
The first three member function pointers take care of the first X::f
overload. The one with default arguments. The last member function pointer
takes care of the second X::f overload.
With these in hand, we can proceed to define and wrap this for Python:
.def("f", fx1)
.def("f", fx2)
.def("f", fx3)
.def("f", fx4)
[page:1 Default Arguments]
Boost.Python wraps (member) function pointers. Unfortunately, C++ function
@@ -892,8 +952,9 @@ to retrieve the default arguments:
def("f", f); // defaults lost!
Because of this, when wrapping C++ code in earlier versions of
Boost.Python, we had to resort to writing thin wrappers:
Because of this, when wrapping C++ code, we had to resort to manual
wrapping as outlined in the [@overloading.html previous section], or
writing thin wrappers:
// write "thin wrappers"
int f1(int x) { f(x); }
@@ -987,7 +1048,7 @@ You can easily add this constructor to Boost.Python in one shot:
Notice the use of [^init<...>] and [^optional<...>] to signify the default
(optional arguments).
[page:1 Overloading]
[page:1 Auto-Overloading]
It was mentioned in passing in the previous section that
[^BOOST_PYTHON_FUNCTION_OVERLOADS] and [^BOOST_PYTHON_FUNCTION_OVERLOADS]
@@ -1030,56 +1091,17 @@ Notice though that we have a situation now where we have a minimum of zero
It is important to emphasize however that [*the overloaded functions must
have a common sequence of initial arguments]. Otherwise, our scheme above
will not work.
The following illustrates an alternate scheme for manually wrapping an
overloaded member function instead of
[^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS]. Obviously, the same technique
can be applied to wrapping overloaded non- member functions.
We have here our C++ classes:
struct X
{
bool f(int a, double b = 0, char c = 'x')
{
return true;
}
int f(int a, int b, int c)
{
return a + b + c;
};
};
Notice that class X has two overloaded functions with different signatures.
The types of the arguments, and the return are totally different, unlike
above where we have a common sequence of initial arguments.
We shall start by introducing some member function pointer variables:
bool (X::*fx1)(int) = &X::f;
bool (X::*fx2)(int, double) = &X::f;
bool (X::*fx3)(int, double, char)= &X::f;
int (X::*fx4)(int, int, int) = &X::f;
The first three member function pointers take care of the first X::f
overload. The one with default arguments. The last member function pointer
takes care of the second X::f overload.
With these in hand, we can proceed to define and wrap this for Python:
.def("f", fx1)
.def("f", fx2)
.def("f", fx3)
.def("f", fx4)
will not work. If this is not the case, we have to wrap our functions
[@overloading.html manually].
Actually, we can mix and match manual wrapping of overloaded functions and
automatic wrapping through [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] and
its sister, [^BOOST_PYTHON_FUNCTION_OVERLOADS]. Since the first overload
has default arguments, we can use [^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS]
to automatically wrap the first three of the [^def]s above and manually
wrap just the last. Here's how we'll do this:
its sister, [^BOOST_PYTHON_FUNCTION_OVERLOADS]. Following up on our example
presented in the section [@overloading.html on overloading], since the
first overload has default arguments, we can use
[^BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS] to automatically wrap the first
three of the [^def]s above and manually wrap just the last. Here's how
we'll do this:
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(xf_overloads, f, 1, 4)

View File

@@ -0,0 +1,122 @@
<html>
<head>
<!-- Generated by the Spirit (http://spirit.sf.net) QuickDoc -->
<title>Virtual Functions with Default Implementations</title>
<link rel="stylesheet" href="theme/style.css" type="text/css">
<link rel="prev" href="deriving_a_python_class.html">
<link rel="next" href="class_operators_special_functions.html">
</head>
<body>
<table width="100%" height="48" border="0" cellspacing="2">
<tr>
<td><img src="theme/c%2B%2Bboost.gif">
</td>
<td width="85%">
<font size="6" face="Verdana, Arial, Helvetica, sans-serif"><b>Virtual Functions with Default Implementations</b></font>
</td>
</tr>
</table>
<br>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="deriving_a_python_class.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="class_operators_special_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<p>
Recall that in the <a href="class_virtual_functions.html">
previous section</a>, we
wrapped a class with a pure virtual function that we then implemented in
C++ or Python classes derived from it. Our base class:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>Base
</span><span class=special>{
</span><span class=keyword>virtual </span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() = </span><span class=number>0</span><span class=special>;
};
</span></pre></code>
<p>
had a pure virtual function <tt>f</tt>. If, however, its member function <tt>f</tt> was
not declared as pure virtual:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>Base
</span><span class=special>{
</span><span class=keyword>virtual </span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() { </span><span class=keyword>return </span><span class=number>0</span><span class=special>; }
};
</span></pre></code>
<p>
and instead had a default implementation that returns <tt>0</tt>, as shown above,
we need to add a forwarding function that calls the <tt>Base</tt> default virtual
function <tt>f</tt> implementation:</p>
<code><pre>
<span class=keyword>struct </span><span class=identifier>BaseWrap </span><span class=special>: </span><span class=identifier>Base
</span><span class=special>{
</span><span class=identifier>BaseWrap</span><span class=special>(</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self_</span><span class=special>)
: </span><span class=identifier>self</span><span class=special>(</span><span class=identifier>self_</span><span class=special>) {}
</span><span class=keyword>int </span><span class=identifier>f</span><span class=special>() { </span><span class=keyword>return </span><span class=identifier>call_method</span><span class=special>&lt;</span><span class=keyword>int</span><span class=special>&gt;(</span><span class=identifier>self</span><span class=special>, </span><span class=string>&quot;f&quot;</span><span class=special>); }
</span><span class=keyword>int </span><span class=identifier>default_f</span><span class=special>() { </span><span class=keyword>return </span><span class=identifier>Base</span><span class=special>::</span><span class=identifier>f</span><span class=special>(); } // &lt;&lt;=== ***</span><span class=identifier>ADDED</span><span class=special>***
</span><span class=identifier>PyObject</span><span class=special>* </span><span class=identifier>self</span><span class=special>;
};
</span></pre></code>
<p>
Then, Boost.Python needs to keep track of 1) the dispatch function <tt>f</tt> and
2) the forwarding function to its default implementation <tt>default_f</tt>.
There's a special <tt>def</tt> function for this purpose. Here's how it is
applied to our example above:</p>
<code><pre>
<span class=identifier>class_</span><span class=special>&lt;</span><span class=identifier>Base</span><span class=special>, </span><span class=identifier>BaseWrap</span><span class=special>&gt;(</span><span class=string>&quot;Base&quot;</span><span class=special>)
.</span><span class=identifier>def</span><span class=special>(</span><span class=string>&quot;f&quot;</span><span class=special>, &amp;</span><span class=identifier>Base</span><span class=special>::</span><span class=identifier>f</span><span class=special>, &amp;</span><span class=identifier>BaseWrap</span><span class=special>::</span><span class=identifier>default_f</span><span class=special>)
</span></pre></code>
<p>
Note that we are allowing <tt>Base</tt> objects to be instantiated this time,
unlike before where we specifically defined the <tt>class_&lt;Base&gt;</tt> with
<tt>no_init</tt>.</p>
<p>
In Python, the results would be as expected:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>base </span><span class=special>= </span><span class=identifier>Base</span><span class=special>()
&gt;&gt;&gt; </span><span class=keyword>class </span><span class=identifier>Derived</span><span class=special>(</span><span class=identifier>Base</span><span class=special>):
... </span><span class=identifier>def </span><span class=identifier>f</span><span class=special>(</span><span class=identifier>self</span><span class=special>):
... </span><span class=keyword>return </span><span class=number>42
</span><span class=special>...
&gt;&gt;&gt; </span><span class=identifier>derived </span><span class=special>= </span><span class=identifier>Derived</span><span class=special>()
</span></pre></code>
<p>
Calling <tt>base.f()</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>base</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
</span><span class=number>0
</span></pre></code>
<p>
Calling <tt>derived.f()</tt>:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>derived</span><span class=special>.</span><span class=identifier>f</span><span class=special>()
</span><span class=number>42
</span></pre></code>
<p>
Calling <tt>call_f</tt>, passing in a <tt>base</tt> object:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>base</span><span class=special>)
</span><span class=number>0
</span></pre></code>
<p>
Calling <tt>call_f</tt>, passing in a <tt>derived</tt> object:</p>
<code><pre>
<span class=special>&gt;&gt;&gt; </span><span class=identifier>call_f</span><span class=special>(</span><span class=identifier>derived</span><span class=special>)
</span><span class=number>42
</span></pre></code>
<table border="0">
<tr>
<td width="30"><a href="../index.html"><img src="theme/u_arr.gif" border="0"></a></td>
<td width="30"><a href="deriving_a_python_class.html"><img src="theme/l_arr.gif" border="0"></a></td>
<td width="20"><a href="class_operators_special_functions.html"><img src="theme/r_arr.gif" border="0"></a></td>
</tr>
</table>
<br>
<hr size="1"><p class="copyright">Copyright &copy; 2002-2003 David Abrahams<br>Copyright &copy; 2002-2003 Joel de Guzman<br><br>
<font size="2">Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This document
is provided &quot;as is&quot; without express or implied warranty, and with
no claim as to its suitability for any purpose. </font> </p>
</body>
</html>

View File

@@ -60,6 +60,16 @@
<a href="doc/class_virtual_functions.html">Class Virtual Functions</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/deriving_a_python_class.html">Deriving a Python Class</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/virtual_functions_with_default_implementations.html">Virtual Functions with Default Implementations</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/class_operators_special_functions.html">Class Operators/Special Functions</a>
@@ -75,6 +85,11 @@
<a href="doc/call_policies.html">Call Policies</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/overloading.html">Overloading</a>
</td>
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/default_arguments.html">Default Arguments</a>
@@ -82,7 +97,7 @@
</tr>
<tr>
<td class="toc_cells_L1">
<a href="doc/overloading.html">Overloading</a>
<a href="doc/auto_overloading.html">Auto-Overloading</a>
</td>
</tr>
<tr>