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 "будет применяться вместо?