|
| 1 | +<?xml version='1.0' encoding='utf-8' standalone='no'?> |
| 2 | +<!DOCTYPE issue SYSTEM "lwg-issue.dtd"> |
| 3 | + |
| 4 | +<issue num="4381" status="New"> |
| 5 | +<title>`std::ranges::to specification` using CTAD not supported by core language |
| 6 | +</title> |
| 7 | +<section> |
| 8 | +<sref ref="[range.utility.conv.to]"/> |
| 9 | +</section> |
| 10 | +<submitter>Jens Maurer</submitter> |
| 11 | +<date>23 Sep 2025</date> |
| 12 | +<priority>99</priority> |
| 13 | + |
| 14 | +<discussion> |
| 15 | +<p> |
| 16 | +<sref ref="[range.utility.conv.to]"/> p4 defines a <tt><i>DEDUCE_EXPR</i></tt> |
| 17 | +that attempts CTAD (class template argument deduction) on a template template |
| 18 | +parameter `C`. |
| 19 | +<p/> |
| 20 | +This is not supported by the core language; |
| 21 | +<a href="https://cplusplus.github.io/CWG/issues/3003.html">CWG 3003</a> will |
| 22 | +clarify the core wording accordingly. |
| 23 | +<p/> |
| 24 | +Suggested resolution: Remove <sref ref="[range.utility.conv.to]"/> p3, p4, p5 |
| 25 | +and the respective entry in the synopsis as unimplementable. |
| 26 | +</p> |
| 27 | +</discussion> |
| 28 | + |
| 29 | +<resolution> |
| 30 | +<p> |
| 31 | +This wording is relative to <paper num="N5014"/>. |
| 32 | +</p> |
| 33 | + |
| 34 | +<ol> |
| 35 | + |
| 36 | +<li><p>Modify <sref ref="[ranges.syn]"/>, header <tt><ranges></tt> synopsis, as indicated:</p> |
| 37 | + |
| 38 | +<blockquote> |
| 39 | +<pre> |
| 40 | +[…] |
| 41 | +namespace std::ranges { |
| 42 | + […] |
| 43 | + // <i><sref ref="[range.utility.conv]"/>, range conversions</i> |
| 44 | + template<class C, input_range R, class... Args> requires (!view<C>) |
| 45 | + constexpr C to(R&& r, Args&&... args); |
| 46 | + <del>template<template<class...> class C, input_range R, class... Args> |
| 47 | + constexpr auto to(R&& r, Args&&... args);</del> |
| 48 | + template<class C, class... Args> requires (!view<C>) |
| 49 | + constexpr auto to(Args&&... args); |
| 50 | + template<template<class...> class C, class... Args> |
| 51 | + constexpr auto to(Args&&... args); |
| 52 | + […] |
| 53 | +} |
| 54 | +</pre> |
| 55 | +</blockquote> |
| 56 | + |
| 57 | +</li> |
| 58 | + |
| 59 | +<li><p>Modify <sref ref="[range.utility.conv.to]"/> as indicated:</p> |
| 60 | + |
| 61 | +<blockquote> |
| 62 | +<pre> |
| 63 | +<del>template<template<class...> class C, input_range R, class... Args> |
| 64 | + constexpr auto to(R&& r, Args&&... args);</del> |
| 65 | +</pre> |
| 66 | +<blockquote> |
| 67 | +<p> |
| 68 | +<del>-3- Let <tt><i>input-iterator</i></tt> be an exposition-only type:</del> |
| 69 | +</p> |
| 70 | +<blockquote><pre><del> |
| 71 | +struct <i>input-iterator</i> { <i>// exposition only</i> |
| 72 | + using iterator_category = input_iterator_tag; |
| 73 | + using value_type = range_value_t<R>; |
| 74 | + using difference_type = ptrdiff_t; |
| 75 | + using pointer = add_pointer_t<range_reference_t<R>>; |
| 76 | + using reference = range_reference_t<R>; |
| 77 | + reference operator*() const; |
| 78 | + pointer operator->() const; |
| 79 | + <i>input-iterator</i>& operator++(); |
| 80 | + <i>input-iterator</i> operator++(int); |
| 81 | + bool operator==(const <i>input-iterator</i>&) const; |
| 82 | +}; |
| 83 | +</del></pre></blockquote> |
| 84 | +<p> |
| 85 | +<del>[<i>Note 1</i>: <tt><i>input-iterator</i></tt> meets the syntactic requirements of |
| 86 | +<i>Cpp17InputIterator</i>. — <i>end note</i>]</del> |
| 87 | +<p/> |
| 88 | +<del>-4- Let <tt><i>DEDUCE_EXPR</i></tt> be defined as follows:</del> |
| 89 | +</p> |
| 90 | +<ol style="list-style-type: none"> |
| 91 | +<li><p><del>(4.1) — <tt>C(declval<R>(), declval<Args>()...)</tt> if that is a valid expression,</del></p></li> |
| 92 | +<li><p><del>(4.2) — otherwise, <tt>C(from_range, declval<R>(), declval<Args>()...)</tt> if |
| 93 | +that is a valid expression,</del></p></li> |
| 94 | +<li><p><del>(4.3) — otherwise,</del></p> |
| 95 | +<blockquote><pre><del> |
| 96 | +C(declval<<i>input-iterator</i>>(), declval<<i>input-iterator</i>>(), declval<Args>()...) |
| 97 | +</del></pre></blockquote> |
| 98 | +<p><del>if that is a valid expression,</del></p> |
| 99 | +</li> |
| 100 | +<li><p><del>(4.4) — otherwise, the program is ill-formed.</del></p></li> |
| 101 | +</ol> |
| 102 | +<p> |
| 103 | +<del>-5- <i>Returns</i>: <tt>to<decltype(<i>DEDUCE_EXPR</i>)>(std::forward<R>(r), std::forward<Args>(args)...)</tt>.</del> |
| 104 | +</p> |
| 105 | +</blockquote> |
| 106 | +</blockquote> |
| 107 | + |
| 108 | +</li> |
| 109 | + |
| 110 | +</ol> |
| 111 | +</resolution> |
| 112 | + |
| 113 | +</issue> |
0 commit comments