From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 5E95B3861841; Wed, 8 Jul 2020 13:22:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5E95B3861841 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1594214564; bh=2RP0/KF3w36dagA4tecsNVZeH5SrlzEL8pS9cH3GgSA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=rBSrfVzMfSt5/gy3YPI/VA7deVoPhExp8sojjKUB4NnILKlR1jW+cpkTq1KeqYCbZ 6yzvA0yEE3CKJU/IwAW3MUfBdaslrs6f5ZJpBOpOtmfZhFIGFiwSyk8VQbJg+753eb Qa2LNmqFKU7PxD7l7fx5uzXAKVwB7t9k499Qbz7E= From: "ppalka at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/95910] transform view in combination with single view calls const qualified begin even if it is not const Date: Wed, 08 Jul 2020 13:22:44 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: 10.1.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: ppalka at gcc dot gnu.org X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Jul 2020 13:22:44 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D95910 --- Comment #3 from Patrick Palka --- (In reply to Rene Rahn from comment #2) > Ok, thanks for the explanation. I do understand the issue now and why it > causes the hard error and not an substitution failure.=20 > But honestly, given that it works for container because they are wrapped = in > a ref_view with pointer semantics, makes this very hard to understand. Hmm yes, it seems (for the record) the reason this works for std::vector is because views::transform wraps the type in a ref_view, and ref_view's const-qualified begin() member returns a non-const iterator. So both range_reference_t<_Vp> and range_reference_t (where _Vp =3D ref_view>) resolve to int&. On the other hand, single_view's const-qualified begin() member returns a pointer to const T, so range_reference_t (with _Vp =3D single_vi= ew) resolves to const int&. And so when we go to check the constraints of=20 transform_view::begin() const we end up instantiating the lambda with a con= st int& argument, leading to a hard error. > And basically, if you transform something that calls somewhere in the sta= ck a > function with auto return type you might not be able to even do > `decltype(expression)` to get the return type deduced any more, because t= he > compiler has to instantiate the expression.=20 >=20 > That makes generic code with auto return types kind of difficult to use, > does it? I mean, especially as a library writer I must make sure that the > client can use my methods/types in these contexts. And it feels plausible > that types are constrained to be mutable somewhere in this context. > Is there a general trick to avoid this, except guaranteeing to know the > return type before the expression is evaluated? Hmm, if you can't easily specify a concrete return type, then you could may= be try constraining the lambda appropriately. In this particular example you could replace the static_assert with an analogous require-clause, which wou= ld turn the hard error into a SFINAE-friendly error. We've also been bitten by using a deduced auto return type instead of a concrete return type, in particular in the definitions of the ranges::empty= () and ranges::iter_move() CPOs, see e.g. PR93978 and PR92894.=20 >=20 > Many thanks for your help!=