Here\'s a minimum code example that illustrates the problem:
#include
class Thing
{
// Non-copyable
Thing(const Thing&);
Thing
My gut feeling is that Jerry's answer is correct, but there are a few questions still.
What is interesting is that there is a core issue covering the previous paragraph of that section (391). That issue relates to when the argument is the same class type. Specifically:
int main () {
show ( Thing (3) ); // not allowed under current wording
// but allowed with Core Issue 391
show ( 3 ); // Still illegal with 391
}
The change in Core Issue 391 only affects where the rvalue temporary has the same class type. The previous wording had:
If the initializer expression is an rvalue, with T2 a class type, and
cv1 T1is reference-compatible withcv2 T2,the reference is bound as follows:[...]
The constructor that would be used to make the copy shall be callable whether or not the copy is actually done.
That last line is what would make show(Thing(3)) illegal as per the current standard. The proposed wording for this section is:
If the initializer expression is an rvalue, with T2 a class type, and "cv1 T1" is reference-compatible with "cv2 T2", the reference is bound to the object represented by the rvalue (see 3.10 [basic.lval]) or to a sub-object within that object.
At this point, I considered that g++ may have updated its behaviour as per 391 but that the change accidentally included the copy-initialization case. However, that is not demonstrated by the versions of g++ that I tested with:
class A{
public:
A ();
A (int);
private:
A (A const &);
};
void foo (A const &);
void foo ()
{
A a = 3 ; // 3.2.3 (ERROR), 3.4.6(ERROR), 4.4.0(ERROR), Comeau(ERROR)
foo ( 3 ) ; // 3.2.3 (OK), 3.4.6(OK), 4.4.0(OK), Comeau(OK)
foo ( A() ); // 3.2.3 (OK), 3.4.6(ERROR), 4.4.0(OK), Comeau(OK)
foo ( A(3) ); // 3.2.3 (OK), 3.4.6(ERROR), 4.4.0(OK), Comeau(OK)
}
I cannot find fault in Jerry's interpretation for the foo (3) case, however, I do have doubts due to the discrepency between the different compiler behaviours.