Подтвердить что ты не робот

Должно ли это быть двусмысленным или нет? (неявные отбрасывания)

 struct A 
 {
     A(const A& src);
     A(const char* src);
 };
 struct B 
 {
     operator A();
     operator char*();
 };
 void test()  
 {
     B v;
     A s(v);
 }

EDG/Comeau и MSVC позволяют использовать код в то время как GCC 4.4.4, CLANG и BCC отвергайте его как двусмысленный.

Член комитета С++ ответил с этим (изначально):

Это не двусмысленно; A (const A &) конструктор лучше, чем A (const char *). Константа A & параметр привязывается непосредственно к результату функции преобразования, поэтому последовательность преобразования считается последующее преобразование, определяемое пользователем путем преобразования идентичности (13.3.3.1.4p1). Const char * параметр - это пользовательское преобразование с последующей квалификацией конверсии, так что это хуже.

Затем он продолжил это.

Собственно, я был неправ. Хотя это верно, что второе преобразование последовательность в пользовательском преобразовании последовательность - тай-брейк, выглядящий больше близко к 13.3.3.2p3, следующая-последняя пуля, показывает, что это тай-брейк применяется только в том случае, если последовательности содержат одинаковые определяемая пользователем последовательность преобразований и это не так в этом примере. Поскольку одно преобразование конструктора последовательность использует оператор B:: operator A() и другие используют b:: operator char *(), там нет тай-брейкера между двумя пользовательские последовательности преобразования и они неоднозначны.

Мой вопрос таков.

13.3.3.2 p3 утверждает, что

Две неявные последовательности преобразования одна и та же форма неразличима последовательности преобразований, если один из применяются следующие правила.

По моему мнению, ключевые слова являются "одним из следующих правил". Это не означает, что пуля, которая содержит "одну и ту же последовательность преобразований", переопределяет все перечисленные выше. Я бы подумал: "Ранг S1 лучше чем ранг S2 "будет применяться вместо?

4b9b3361

Ответ 1

Да, ожидаемый результат - это неоднозначность в лучшую сторону моей интерпретации пункта 13.3.3.2.

Соответствующий аргумент 'v' типа 'B' для параметров любого из перегруженных конструкторов 'A' требует определенного преобразования. Там обе последовательности имеют ранг CONVERSION.

Моя интерпретация заключается в том, что применяется следующая цитата из статьи 13.3.3.2.

[...] Пользовательская последовательность преобразований U1 является лучшей последовательностью преобразования чем другое пользовательское преобразование последовательность U2 , если они содержат одинаковые пользовательская функция преобразования или конструктор, и если второй стандарт последовательность преобразования U1 лучше чем второе стандартное преобразование последовательность U2.

Оба они вызывают разные функции преобразования в классе "B". Поэтому я думаю, что первое условие не выполняется, и, следовательно, ожидаемым результатом является неоднозначность, поскольку ни одна из последовательностей преобразования не лучше другой.

Ответ 2

Отказ от ответственности: стандарт действительно сложный на этих частях, поэтому я могу быть совершенно неправым в своем понимании.

Стандартное определение наилучшей жизнеспособной функции (13.3.3):

Учитывая эти определения, жизнеспособный функция F1 определена как лучшая функции, чем другая жизнеспособная функция F2, если для всех аргументов i, ICSi (F1) не хуже конверсионной последовательности, чем ICSi (F2), а затем

[...]

  • контекст инициализация с помощью пользовательского преобразования (см. 8.5, 13.3.1.5 и 13.3.1.6) и стандартную последовательность преобразования из вернуть тип F1 в пункт назначения тип (т.е. тип объекта инициализируется) лучше последовательность преобразования, чем стандартная последовательность преобразования из возвращаемого тип F2 к типу назначения.

Если я правильно понимаю, тип создаваемого объекта имеет здесь значение, и это сделает A::A(const A &) лучшим кандидатом. Забастовкa >


Обратитесь к комментариям Йоханнеса, чтобы понять, почему этот ответ неверен: это действительно двусмысленно по причине, отмеченной Chubsdad.