Должно ли это быть двусмысленным или нет? (неявные отбрасывания)
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 "будет применяться вместо?
Ответы
Ответ 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.