У меня такое чувство, что ответ Джерри правильный, но есть еще несколько вопросов.
Что интересно, так это то, что существует ключевая проблема, охватывающая предыдущий абзац этого раздела ( 391 ). Эта проблема связана с тем, когда аргумент имеет тот же тип класса. В частности:
int main () {
show ( Thing (3) ); // not allowed under current wording
// but allowed with Core Issue 391
show ( 3 ); // Still illegal with 391
}
Изменение в основной проблеме 391 влияет только в том случае, если временное значение rvalue имеет тот же тип класса. Предыдущая формулировка имела:
Если выражение инициализатора является r-значением, у T2 - тип класса, а cv1 T1
совместимо со ссылками с cv2 T2,
, ссылка связывается следующим образом:
[...]
Конструктор, который будет использоваться для создания копии, должен вызываться независимо от того, выполняется ли копия на самом деле.
Эта последняя строка - то, что делает show(Thing(3))
недопустимым в соответствии с текущим стандартом. Предлагаемая формулировка для этого раздела:
Если выражение инициализатора является rvalue, с T2 типом класса, и "cv1 T1" совместим со ссылками с "cv2 T2", ссылка привязывается к объекту, представленному rvalue (см. 3.10 [basic.lval ]) или подобъекту внутри этого объекта.
В этот момент я считал, что g ++, возможно, обновил свое поведение согласно 391 , но это изменение случайно включило случай инициализации копирования. Однако это не продемонстрировано версиями g ++, которые я тестировал:
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)
}
Я не могу найти ошибку в интерпретации Джерри для случая foo (3)
, однако у меня есть сомнения из-за несоответствия между различными поведениями компилятора.