[Bug c++/82171] Cant use std::declval in concept testing map operator[]

daniel.kruegler at googlemail dot com gcc-bugzilla@gcc.gnu.org
Mon Sep 11 18:16:00 GMT 2017


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82171

Daniel Krügler <daniel.kruegler at googlemail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |daniel.kruegler@googlemail.
                   |                            |com

--- Comment #2 from Daniel Krügler <daniel.kruegler at googlemail dot com> ---
(In reply to Robert Douglas from comment #1)
> I came about this, transitioning from habits using SFINAE. I have just
> realized I can simplify it to:
> template<typename T>
> concept bool MapLike = requires(T t) {
>     {t[typename T::value_type::first_type{}]}
>         -> typename T::value_type::second_type;
> };

IMO a better approach imposing less unnecessary constraints (such as
list-initialization) would be something along the lines of:

template<typename T>
concept bool MapLike = requires(T t, typename T::value_type::first_type ft) {
    {t[ft]} -> typename T::value_type::second_type;
};

> and bypass the declval, altogether. Question, though, does anything forbid
> declval in this context?

Technically the error results because the definition (and not only the
declaration) of std::declval<typename T::value_type::first_type>() had been
instantiated here, because it seems to be considered as odr-used.

But according to [expr.prim.req] p2: 

"Expressions appearing within a requirement-body are unevaluated operands
(Clause 8)."

and following [expr] p8:

"In some contexts, unevaluated operands appear (8.1.7, 8.2.8, 8.3.3, 8.3.7,
10.1.7.2, Clause 17). An unevaluated operand is not evaluated. [Note: In an
unevaluated operand, a non-static class member may be named (8.1) and naming of
objects or functions does not, by itself, require that a definition be provided
(6.2). An unevaluated operand is considered a full-expression (4.6). — end
note]"

As I understand it, this wording should allow using std::declval within the
requirement-body as you did it without causing it being considered odr-used, so
the current behaviour looks like a bug to me.


More information about the Gcc-bugs mailing list