On 18/02/2020 02:20, Patrick Palka wrote:
On Mon, 17 Feb 2020, Stephan Bergmann wrote:
On 04/02/2020 03:07, Patrick Palka wrote:
This patch implements [range.adaptors]. It also includes the changes from
P3280
and P3278 and P3323, without which many standard examples won't work.
I see that with this
<https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;a=commit;h=cba9ef069e58eac00f30489d3ef21390caee6e45>
"libstdc++: Implement C++20 range adaptors", compiling <ranges> with recent
Clang trunk (which appears to mostly implement C++20 concepts now) in
-std=c++2a mode fails as below (besides also failing due to some "missing"
typenames, where Clang apparently doesn't yet implement P0634R3). And I'm not
sure which of Clang vs. GCC is right here.
The failure is
gcc/trunk/inst/include/c++/10.0.1/ranges:1512:47: error: ambiguous deduction
for template arguments of '_RangeAdaptor'
inline constexpr __adaptor::_RangeAdaptor filter
^
gcc/trunk/inst/include/c++/10.0.1/ranges:1073:2: note: candidate function
[with _Callable = std::ranges::views::(lambda at
gcc/trunk/inst/include/c++/10.0.1/ranges:1513:9)]
_RangeAdaptor(const _Callable& = {})
^
gcc/trunk/inst/include/c++/10.0.1/ranges:1078:2: note: candidate function
[with _Callable = std::ranges::views::(lambda at
gcc/trunk/inst/include/c++/10.0.1/ranges:1513:9)]
_RangeAdaptor(_Callable __callable)
^
and a stripped-down reproducer is
template<typename T> struct S {
S(T const &) requires true;
S(T) requires false;
};
S s = 0;
(Clang accepts this when the last line is replaced with
S<int> s = 0;
and thus no class template argument deduction needs to be done.)
I think what is relevant here is [over.match.class.deduct]/1 in the current
spec, which specifies a helper set of hypothetical function templates based on
a class' constructors for class template argument deduction. It details the
function templates' template parameters, function parameters, and return
types, but does not mention requires-clauses. From my superficial
understanding of concepts and class template argument deduction it would thus
look like the constructors' requires-clauses should indeed not be taken into
account here?
Thanks for letting me know about this issue. That would be my
interpretation of the spec, too. Maybe someone else could shed light on
this question?
The following patch simplifies _RangeAdaptor's constructors to no longer
need to be constrained and should resolve the deduction ambiguity error
reported by Clang? Unfortunately the patch triggers an ICE in GCC,
which I'll look into tomorrow.
Thanks, I can confirm that patch works fine with Clang.
Btw, the "missing" typenames for Clang I mentioned above would be fixed
with the following patch. I don't know whether you would want to do
that, as technically the current C++20-only code is fine, but here it is
anyway:
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 970e904bddd..c487dd612c2 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -1326,7 +1326,7 @@ namespace views
static constexpr auto
_S_iter_cat()
{
- using _Cat = iterator_traits<iterator_t<_Vp>>::iterator_category;
+ using _Cat = typename
iterator_traits<iterator_t<_Vp>>::iterator_category;
if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
return bidirectional_iterator_tag{};
else if constexpr (derived_from<_Cat, forward_iterator_tag>)
@@ -1549,7 +1549,7 @@ namespace views
static constexpr auto
_S_iter_cat()
{
- using _Cat = iterator_traits<iterator_t<_Base>>::iterator_category;
+ using _Cat = typename
iterator_traits<iterator_t<_Base>>::iterator_category;
if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
return random_access_iterator_tag{};
else
@@ -2294,9 +2294,9 @@ namespace views
_S_iter_cat()
{
using _OuterCat
- = iterator_traits<iterator_t<_Base>>::iterator_category;
+ = typename iterator_traits<iterator_t<_Base>>::iterator_category;
using _InnerCat
- = iterator_traits<iterator_t<range_reference_t<_Base>>>
+ = typename iterator_traits<iterator_t<range_reference_t<_Base>>>
::iterator_category;
if constexpr (_S_ref_is_glvalue
&& derived_from<_OuterCat, bidirectional_iterator_tag>
@@ -2765,7 +2765,7 @@ namespace views
static constexpr auto
_S_iter_cat()
{
- using _Cat = iterator_traits<iterator_t<_Base>>::iterator_category;
+ using _Cat = typename
iterator_traits<iterator_t<_Base>>::iterator_category;
if constexpr (derived_from<_Cat, forward_iterator_tag>)
return forward_iterator_tag{};
else