forked from lwg/issues
-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New issue from Hewill: "Range adaptor closure object is underspecifie…
…d for its return type"
- Loading branch information
Showing
1 changed file
with
76 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
<?xml version='1.0' encoding='utf-8' standalone='no'?> | ||
<!DOCTYPE issue SYSTEM "lwg-issue.dtd"> | ||
|
||
<issue num="3981" status="New"> | ||
<title>Range adaptor closure object is underspecified for its return type</title> | ||
<section><sref ref="[range.adaptor.object]"/></section> | ||
<submitter>Hewill Kang</submitter> | ||
<date>22 Aug 2023</date> | ||
<priority>99</priority> | ||
|
||
<discussion> | ||
<p> | ||
In order to provide pipe support for user-defined range adaptors, <paper num="P2387R3"/> | ||
removed the specification that the adaptor closure object returns a view, which conforms to the wording of <tt>ranges::to</tt>. | ||
<p/> | ||
However, the current wording seems to be too low-spec so that the range adaptor closure object can return any type | ||
or even <tt>void</tt>. This makes it possible to break the previous specification when returning types that don't make sense, | ||
<a href="https://godbolt.org/z/Y4nvjY3xj">for example</a>: | ||
</p> | ||
<blockquote> | ||
<pre> | ||
#include <ranges> | ||
|
||
struct Closure : std::ranges::range_adaptor_closure<Closure> { | ||
struct NonCopyable { | ||
NonCopyable(const NonCopyable&) = delete; | ||
}; | ||
|
||
const NonCopyable& operator()(std::ranges::range auto&&); | ||
}; | ||
|
||
auto r = std::views::iota(0) | Closure{}; // <span style="color:red;font-weight:bolder">hard error in stdlibc++ and MSVC-STL</span> | ||
</pre></blockquote> | ||
<p> | ||
Above, since the return type of the pipeline operator is declared as <tt>auto</tt>, this causes the deleted | ||
copy constructor to be invoked in the function body and produces a hard error. | ||
<p/> | ||
The proposed resolution adds a specification for the range adaptor closure object to return a <i>cv</i>-unqualified class type. | ||
</p> | ||
</discussion> | ||
|
||
<resolution> | ||
<p> | ||
This wording is relative to <paper num="N4958"/>. | ||
</p> | ||
|
||
<ol> | ||
|
||
<li><p>Modify the <sref ref="[range.adaptor.object]"/> as indicated:</p> | ||
|
||
<blockquote> | ||
<p> | ||
-1- A <i>range adaptor closure object</i> is a unary function object that accepts a range argument. For a range adaptor | ||
closure object <tt>C</tt> and an expression <tt>R</tt> such that <tt>decltype((R))</tt> models <tt>range</tt>, the | ||
following expressions are equivalent: | ||
</p> | ||
<p>[…]</p> | ||
<p> | ||
-2- Given an object <tt>t</tt> of type <tt>T</tt>, where | ||
</p> | ||
<ol style="list-style-type: none"> | ||
<li><p>(2.1) — <tt>t</tt> is a unary function object that accepts a range argument <ins>and returns a | ||
<i>cv</i>-unqualified class object</ins>,</p></li> | ||
<p>[…]</p> | ||
</ol> | ||
<p> | ||
then the implementation ensures that <tt>t</tt> is a range adaptor closure object. | ||
</p> | ||
</blockquote> | ||
|
||
</li> | ||
|
||
</ol> | ||
</resolution> | ||
|
||
</issue> |