Consider the following case
struct A {
operator int();
};
int &&x = A();
The spec says at http://eel.is/c++draft/dcl.init.ref#5 about whether the reference binding is direct or indirect
In all cases except the last (i.e., creating and initializing a temporary from the initializer expression), the reference is said to bind directly to the initializer expression.
The case above doesn't match the last, but the second last bullet.
If T1 or T2 is a class type and T1 is not reference-related to T2, user-defined conversions are considered ... The result of the call to the conversion function, as described for the non-reference copy-initialization, is then used to direct-initialize the reference.
Therefore the binding of A()
to the reference is indirect binding. To carry on, we will recurse into reference initialization again, now with a prvalue of type int
, trying to initialize int&&
. Now we will end up with the last bullet, which means direct binding.
So what can we say about the binding of the reference... does it bind directly or indirectly? Does it do both, depending on what expression you consider (initializer expression vs result of the conversion function call)?
In our case in particular, the paragraphs seem to say we bind directly to the initializer expression and bind indirectly to the result of the conversion on the initializer expression. However, in the chapter on overload resulution http://eel.is/c++draft/over.ics.ref, we only distinguish between
- When a parameter of reference type binds directly ([dcl.init.ref]) to an argument expression,
- If the parameter binds directly to the result of applying a conversion function to the argument expression,
- When a parameter of reference type is not bound directly to an argument expression,
For a case like
void f(int &&);
f(A());
Case 1 applies, but I'm pretty sure it is not intended to apply. My gut feeling is that "In all cases except the last" is not only intended to match the creation-of-temporary case, but also the second last bullet or alternatively to the whole "Otherwise:" branch that contains the two bullets (i.e the "last" refers to a different level on the bullet-hierarchy). Can you please clarify?