
I take that back -- the Intel compiler is right, GCC and MSVC are wrong.
void g(int const volatile&); void g(...);
When calling g with an int rvalue, the compiler must select the `void g(int const volatile&)` overload because "a standard conversion sequence is a better conversion sequence than a user-defined conversion sequence or an ellipsis conversion sequence". Only then does the compiler decide that calling `void g(int const volatile&)` with an int rvalue is illegal. And this is not without precendence -- quoting §13.3.3.1.4/4:
Other restrictions on binding a reference to a particular argument do not affect the formation of a standard conversion sequence, however. [Example: a function with a "reference to int" parameter can be a viablecandidate even if the corresponding argument is an int bit-field. The formation of implicit conversion sequences treats the int bit-field as an int lvalue and finds an exact match with the parameter. If the function is selected by overload resolution, the call will nonetheless be ill-formed because of the prohibition on binding a non-const reference to a bit-field.]
Summary: Intel *is correct* according to the standarde, but GCC and MSVC take the sane/practical route.
I am not sure of your interpretation. Here are other parts of the standard: § 13.3.2 Viable functions: "for F to be a viable function, there shall exist for each argument an implicit conversion sequence (13.3.3.1) that converts that argument to the corresponding parameter of F. If the parameter has reference type, the implicit conversion sequence includes the operation of binding the reference, and the fact that a reference to non-const cannot be bound to an rvalue can affect the viability of the function (see 13.3.3.1.4)." § 13.3.3.1.4/3: "A standard conversion sequence cannot be formed if it requires binding a reference to non-const to an rvalue (except when binding an implicit object parameter; see the special rules for that case in 13.3.1). [Note: this means, for example, that a candidate function cannot be a viable function if it has a non-const reference parameter (other than the implicit object parameter) and the corresponding argument is a temporary or would require one to be created to initialize the reference (see 8.5.3). ]" So the question is: is "const volatile &" a "reference to non-const"? Or does "reference to non-const" mean exaclty T const & (excluding additionnal volatile qualifier) or not? If T const volatile & is considered as "reference to non-const" then Intel is wrong. If not, Intel is right. §8.5.3/5 you quoted earlier suggests that "reference to non-const" is only T const & which would mean that Intel is wrong: "A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows: — If the initializer expression — is an lvalue (but is not a bit-field), and “cv1 T1” is reference-compatible with “cv2 T2,” or — has a class type (i.e., T2 is a class type) and ... — Otherwise, the reference shall be to a non-volatile const type (i.e., cv1 shall be const)." Frédéric