Add docs for C++11 ref-qualifiers
This commit is contained in:
parent
8a40327aa8
commit
330ef362f4
5 changed files with 150 additions and 6 deletions
|
|
@ -7,6 +7,29 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
|||
Version 4.0.0 (in progress)
|
||||
===========================
|
||||
|
||||
2017-08-25: wsfulton
|
||||
Issue #1059. Add support for C++11 ref-qualifiers on non-static member functions.
|
||||
Members with lvalue ref-qualifiers such as:
|
||||
|
||||
struct RQ {
|
||||
void m1(int x) &;
|
||||
void m2(int x) const &;
|
||||
};
|
||||
|
||||
are wrapped like any other member function. Member functions with rvalue ref-qualifiers
|
||||
are ignored by default, such as:
|
||||
|
||||
struct RQ {
|
||||
void m3(int x) &&;
|
||||
void m4(int x) const &&;
|
||||
};
|
||||
|
||||
example.i:7: Warning 405: Method with rvalue ref-qualifier m3(int) && ignored.
|
||||
example.i:8: Warning 405: Method with rvalue ref-qualifier m4(int) const && ignored.
|
||||
|
||||
These can be unignored and exposed to the target language, see further documentation in
|
||||
CPlusPlus11.html.
|
||||
|
||||
2017-08-16: wsfulton
|
||||
Fix #1063. Add using declarations to templates into typedef table.
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
<li><a href="#CPlusPlus11_noexcept">Exception specifications and noexcept</a>
|
||||
<li><a href="#CPlusPlus11_alignment">Control and query object alignment</a>
|
||||
<li><a href="#CPlusPlus11_attributes">Attributes</a>
|
||||
<li><a href="#CPlusPlus11_ref_qualifiers">Methods with ref-qualifiers</a>
|
||||
</ul>
|
||||
<li><a href="#CPlusPlus11_standard_library_changes">Standard library changes</a>
|
||||
<ul>
|
||||
|
|
@ -971,6 +972,104 @@ int [[attr1]] i [[attr2, attr3]];
|
|||
[[noreturn, nothrow]] void f [[noreturn]] ();
|
||||
</pre></div>
|
||||
|
||||
|
||||
<H3><a name="CPlusPlus11_ref_qualifiers">7.2.29 Methods with ref-qualifiers</a></H3>
|
||||
|
||||
|
||||
<p>
|
||||
C++11 non-static member functions can be declared with ref-qualifiers.
|
||||
Member functions declared with a <tt>&</tt> lvalue ref-qualifiers are wrapped like any other function without ref-qualifiers.
|
||||
Member functions declared with a <tt>&&</tt> rvalue ref-qualifiers are ignored by default
|
||||
as they are unlikely to be required from non-C++ languages where the concept of <i>rvalue-ness</i>
|
||||
for the implied *this pointer does not apply.
|
||||
The warning is hidden by default, but can be displayed as described in the section on <a href="Warnings.html#Warnings_nn4">Enabling extra warnings</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Consider:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
struct RQ {
|
||||
void m1(int x) &;
|
||||
void m2(int x) &&;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
The only wrapped method will be the lvalue ref-qualified method <tt>m1</tt>
|
||||
and if SWIG is run with the <tt>-Wextra</tt> command-line option, the following warning will be issued indicating <tt>m2</tt> is not wrapped:
|
||||
</p>
|
||||
|
||||
<div class="shell">
|
||||
<pre>
|
||||
example.i:7: Warning 405: Method with rvalue ref-qualifier m2(int) && ignored.
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
If you unignore the method as follows, wrappers for <tt>m2</tt> will be generated:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%feature("ignore", "0") RQ::m2(int x) &&;
|
||||
struct RQ {
|
||||
void m1(int x) &;
|
||||
void m2(int x) &&;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
Inspection of the generated C++ code, will show that <tt>std::move</tt> is used on the instance
|
||||
of the <tt>RQ *</tt> class:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
RQ *arg1 = (RQ *) 0 ;
|
||||
int arg2 ;
|
||||
|
||||
arg1 = ...marshalled from target language...
|
||||
arg2 = ...marshalled from target language...
|
||||
|
||||
std::move(*arg1).m2(arg2);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
This will compile but when run, the move effects may not be what you want.
|
||||
As stated earlier, rvalue ref-qualifiers aren't really applicable outside the world of C++.
|
||||
However, if you really know what you are doing, full control over the call to the method is
|
||||
possible via the low-level "action" feature.
|
||||
This feature completely replaces the call to the underlying function, that is, the last line in the snippet of code above.
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
%feature("ignore", "0") RQ::m2(int x) &&;
|
||||
%feature("action") RQ::m2(int x) && %{
|
||||
RQ().m2(arg2);
|
||||
%}
|
||||
struct RQ {
|
||||
void m1(int x) &;
|
||||
void m2(int x) &&;
|
||||
};
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
resulting in:
|
||||
</p>
|
||||
|
||||
<div class="code"><pre>
|
||||
RQ *arg1 = (RQ *) 0 ;
|
||||
int arg2 ;
|
||||
|
||||
arg1 = ...marshalled from target language...
|
||||
arg2 = ...marshalled from target language...
|
||||
|
||||
RQ().m2(arg2);
|
||||
</pre></div>
|
||||
|
||||
<p>
|
||||
<b>Compatibility note:</b> SWIG-4.0.0 was the first version to support ref-qualifiers.
|
||||
</p>
|
||||
<H2><a name="CPlusPlus11_standard_library_changes">7.3 Standard library changes</a></H2>
|
||||
|
||||
|
||||
|
|
@ -1177,5 +1276,6 @@ Phew, that is a lot of hard work to get a callback working.
|
|||
You could just go with the more attractive option of just using <tt>double</tt> as the return type in the function declaration instead of <tt>result_of</tt>!
|
||||
</p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -310,6 +310,7 @@
|
|||
<li><a href="CPlusPlus11.html#CPlusPlus11_noexcept">Exception specifications and noexcept</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_alignment">Control and query object alignment</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_attributes">Attributes</a>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_ref_qualifiers">Methods with ref-qualifiers</a>
|
||||
</ul>
|
||||
<li><a href="CPlusPlus11.html#CPlusPlus11_standard_library_changes">Standard library changes</a>
|
||||
<ul>
|
||||
|
|
|
|||
|
|
@ -2409,8 +2409,8 @@ the first renaming rule found on a depth-first traversal of the class hierarchy
|
|||
is used.
|
||||
</li>
|
||||
|
||||
<li><p>The name matching rules strictly follow member qualification rules.
|
||||
For example, if you have a class like this:</p>
|
||||
<li><p>The name matching rules strictly follow member qualifier rules.
|
||||
For example, if you have a class and member with a member that is const qualified like this:</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
|
|
@ -2434,7 +2434,7 @@ the declaration
|
|||
</div>
|
||||
|
||||
<p>
|
||||
will not apply as there is no unqualified member <tt>bar()</tt>. The following will apply as
|
||||
will not apply as there is no unqualified member <tt>bar()</tt>. The following will apply the rename as
|
||||
the qualifier matches correctly:
|
||||
</p>
|
||||
|
||||
|
|
@ -2444,6 +2444,26 @@ the qualifier matches correctly:
|
|||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Similarly for combinations of cv-qualifiers and ref-qualifiers, all the qualifiers must be specified to match correctly:
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
%rename(name) Jam::bar(); // will not match
|
||||
%rename(name) Jam::bar() &; // will not match
|
||||
%rename(name) Jam::bar() const; // will not match
|
||||
%rename(name) Jam::bar() const &; // ok, will match
|
||||
|
||||
class Jam {
|
||||
public:
|
||||
...
|
||||
void bar() const &;
|
||||
...
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
An often overlooked C++ feature is that classes can define two different overloaded members
|
||||
that differ only in their qualifiers, like this:
|
||||
|
|
@ -2476,7 +2496,7 @@ For example we can give them separate names in the target language:
|
|||
<p>
|
||||
Similarly, if you
|
||||
merely wanted to ignore one of the declarations, use <tt>%ignore</tt>
|
||||
with the full qualification. For example, the following directive
|
||||
with the full qualifier. For example, the following directive
|
||||
would tell SWIG to ignore the <tt>const</tt> version of <tt>bar()</tt>
|
||||
above:
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -4021,7 +4021,7 @@ struct X {
|
|||
Forced inclusion of fragments can be used as a replacement for <a href="SWIG.html#SWIG_nn42">code insertion block</a>, ensuring the
|
||||
code block is only generated once.
|
||||
Consider the contents of FileA.i below which first uses a code insertion block and then a forced fragment inclusion to generate code:
|
||||
<p>
|
||||
</p>
|
||||
<div class="code">
|
||||
<pre>
|
||||
// FileA.i
|
||||
|
|
@ -4058,7 +4058,7 @@ The resulting code in the wrappers for FileB.i is:
|
|||
<p>
|
||||
A note of caution must be mentioned when using <tt>%fragment</tt> forced inclusion or code insertion blocks with <tt>%import</tt>.
|
||||
If <tt>%import</tt> is used instead:
|
||||
<p>
|
||||
</p>
|
||||
|
||||
<div class="code">
|
||||
<pre>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue