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)
|
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
|
2017-08-16: wsfulton
|
||||||
Fix #1063. Add using declarations to templates into typedef table.
|
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_noexcept">Exception specifications and noexcept</a>
|
||||||
<li><a href="#CPlusPlus11_alignment">Control and query object alignment</a>
|
<li><a href="#CPlusPlus11_alignment">Control and query object alignment</a>
|
||||||
<li><a href="#CPlusPlus11_attributes">Attributes</a>
|
<li><a href="#CPlusPlus11_attributes">Attributes</a>
|
||||||
|
<li><a href="#CPlusPlus11_ref_qualifiers">Methods with ref-qualifiers</a>
|
||||||
</ul>
|
</ul>
|
||||||
<li><a href="#CPlusPlus11_standard_library_changes">Standard library changes</a>
|
<li><a href="#CPlusPlus11_standard_library_changes">Standard library changes</a>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
@ -971,6 +972,104 @@ int [[attr1]] i [[attr2, attr3]];
|
||||||
[[noreturn, nothrow]] void f [[noreturn]] ();
|
[[noreturn, nothrow]] void f [[noreturn]] ();
|
||||||
</pre></div>
|
</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>
|
<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>!
|
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>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -310,6 +310,7 @@
|
||||||
<li><a href="CPlusPlus11.html#CPlusPlus11_noexcept">Exception specifications and noexcept</a>
|
<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_alignment">Control and query object alignment</a>
|
||||||
<li><a href="CPlusPlus11.html#CPlusPlus11_attributes">Attributes</a>
|
<li><a href="CPlusPlus11.html#CPlusPlus11_attributes">Attributes</a>
|
||||||
|
<li><a href="CPlusPlus11.html#CPlusPlus11_ref_qualifiers">Methods with ref-qualifiers</a>
|
||||||
</ul>
|
</ul>
|
||||||
<li><a href="CPlusPlus11.html#CPlusPlus11_standard_library_changes">Standard library changes</a>
|
<li><a href="CPlusPlus11.html#CPlusPlus11_standard_library_changes">Standard library changes</a>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
|
||||||
|
|
@ -2409,8 +2409,8 @@ the first renaming rule found on a depth-first traversal of the class hierarchy
|
||||||
is used.
|
is used.
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li><p>The name matching rules strictly follow member qualification rules.
|
<li><p>The name matching rules strictly follow member qualifier rules.
|
||||||
For example, if you have a class like this:</p>
|
For example, if you have a class and member with a member that is const qualified like this:</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
|
|
@ -2434,7 +2434,7 @@ the declaration
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<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:
|
the qualifier matches correctly:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -2444,6 +2444,26 @@ the qualifier matches correctly:
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</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>
|
<p>
|
||||||
An often overlooked C++ feature is that classes can define two different overloaded members
|
An often overlooked C++ feature is that classes can define two different overloaded members
|
||||||
that differ only in their qualifiers, like this:
|
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>
|
<p>
|
||||||
Similarly, if you
|
Similarly, if you
|
||||||
merely wanted to ignore one of the declarations, use <tt>%ignore</tt>
|
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>
|
would tell SWIG to ignore the <tt>const</tt> version of <tt>bar()</tt>
|
||||||
above:
|
above:
|
||||||
</p>
|
</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
|
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.
|
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:
|
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">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
// FileA.i
|
// FileA.i
|
||||||
|
|
@ -4058,7 +4058,7 @@ The resulting code in the wrappers for FileB.i is:
|
||||||
<p>
|
<p>
|
||||||
A note of caution must be mentioned when using <tt>%fragment</tt> forced inclusion or code insertion blocks with <tt>%import</tt>.
|
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:
|
If <tt>%import</tt> is used instead:
|
||||||
<p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
<pre>
|
<pre>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue