Ответ 1
Да, это ошибка в gcc. Это почти core DR976, с той лишь разницей, что в их примере тип назначения - тип некласса:
struct F {
template<class T>
operator const T&() { static T t; return t; }
};
int main() {
F f;
int i = f; // ill-formed
}
Как и в вашем примере, clang accepts и gcc отклоняют этот пример, независимо от выбранного диалекта стандартной версии.
Обратите внимание, что предложение, измененное этим DR (14.8.2.3 [temp.deduct.conv]), не различает типы назначения класса и некласса, поэтому разрешение этого DR применяется к ваш код в равной степени.
В соответствии с измененным предложением 14.8.2.3 компилятор должен:
- определить
P
, тип возврата шаблона функции преобразования, какX<T> const &
иA
, требуемый тип результата, какX<int>
; - разделите ссылку от
P
, указавX<T> const
; - разделите cv-квалификацию от
P
, указавX<T>
; - выводит
T
какint
.
Я бы рекомендовал подать отчет об ошибке на https://gcc.gnu.org/bugzilla/, ссылаясь на этот DR.
Потому что в вашем случае вы переходите к типу класса, существует обходное решение:
X<int> x1 = a; // fails
X<int> x2(a); // OK
X<int> x3 = X<int>(a); // also OK
В прямой инициализации рассматриваются конструкторы типа назначения (8.5p16); конструктор копии по умолчанию X<int>
принимает параметр типа X<int> const&
, к которому, как мы уже видели, gcc с радостью преобразует A
.