Sirraide wrote:

[[stmt.expand]p3](https://eel.is/c++draft/stmt.expand#3) is confusing me a bit 
at the moment:
> For an expression E, let the expressions begin-expr and end-expr be 
> determined as specified in 
> [[stmt.ranged]](https://eel.is/c++draft/stmt.ranged)[.](https://eel.is/c++draft/stmt.expand#3.sentence-1)
>  An expression is 
> [expansion-iterable](https://eel.is/c++draft/stmt.expand#def:expansion-iterable)
>  if it does not have array type and either
> - begin-expr and end-expr are of the form E.begin() and E.end(), or
> - argument-dependent lookups for begin(E) and for end(E) each find at least 
> one function or function 
> template[.](https://eel.is/c++draft/stmt.expand#3.sentence-2)

The sentence ‘begin-expr and end-expr are of the form E.begin() and E.end()’ to 
me presupposes that those expressions are well-formed, but what happens if they 
aren’t? 

Similarly, regarding the second clause, ‘argument-dependent lookups for 
begin(E) and for end(E) each find at least one function or function template’, 
perhaps my standardese is lacking here, but does e.g. ‘finding a function’ 
require that that function be viable (and the single best candidate)? Does 
finding a e.g. deleted function count? Because if you do e.g. ADL for `begin()` 
on a `std::tuple<>`, it’ll find quite a few `begin()`/`end()` functions, but 
none of them actually work for `std::tuple<>`.

Specifically, what happens if e.g.
1. only member `begin()` (or `end()`) exists; or
2. only member `begin()` (or `end()`) exists but is inaccessible (e.g. private, 
deleted, etc.); or
3. member `begin()` and `end()` exist; either (or both) is inaccessible, and we 
have a valid ADL `begin()`/`end()` pair; or
4. only ADL `begin()` (or `end()`) exists; or
5. only ADL `begin()` (or `end()`) exists but is inaccassible; or
6. some mixture of member and ADL `begin()`/`end()` exist, but we don’t have a 
proper `begin()`/`end()` pair; or
7. we have a proper pair but either function (or both) is inaccessible?

For range-based for loops, this is a lot simpler: if anything goes wrong, the 
program is ill-formed; but here, we *sometimes* need to pivot to building a 
destructuring expansion instead. It’s not entirely clear to me which of the 
conditions I listed above constitute an ill-formed program, and which are 
grounds for switching to destructuring instead. GCC and the experimental fork 
also don’t seem to agree with each other on this 
(https://godbolt.org/z/hzfh1x67G).

CC @cor3ntin, @katzdm You probably have a better idea than me what the intent 
behind that paragraph is.

https://github.com/llvm/llvm-project/pull/165195
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to