Недавно я где-то читал (не помню где) об использовании фигурных скобок для разрешения нескольких пользовательских преобразований, но, похоже, есть разница между преобразованием с помощью конструктора и преобразованием с помощью метода преобразования, которого я не понимаю.
Учитывать:
#include <string>
using ::std::string;
struct C {
C() {}
};
struct A {
A(const string& s) {} // Make std::string convertible to A.
operator C() const { return C(); } // Makes A convertible to C.
};
struct B {
B() {}
B(const A& a) {} // Makes A convertible to B.
};
int main() {
B b;
C c;
// This works.
// Conversion chain (all thru ctors): char* -> string -> A -> B
b = {{"char *"}};
// These two attempts to make the final conversion through A's
// conversion method yield compiler errors.
c = {{"char *"}};
c = {{{"char *"}}};
// On the other hand, this does work (not surprisingly).
c = A{"char *"};
}
Теперь я могу неправильно интерпретировать то, что делает компилятор, но (на основе вышеизложенного и дополнительных экспериментов) мне кажется, что он не рассматривает преобразования методом преобразования. Однако, прочитав разделы 4 и 13.3.3.1 стандарта, я не смог понять, почему это так. Каково объяснение?
Обновить
Вот еще одно интересное явление, которое я хотел бы объяснить. Если я добавлю
struct D {
void operator<<(const B& b) {}
};
и в main
:
D d;
d << {{ "char *" }};
Я получаю сообщение об ошибке, но если вместо этого я пишу d.operator<<({{ "char *" }});
, все работает нормально.
Обновление 2
Похоже, раздел 8.5.4 стандарта может содержать некоторые ответы. Я сообщу о своих выводах.
A
для использования егоoperator C
противоречит этому. - person Peter   schedule 27.05.2016c = A{...
илиc = {A{...
, он отлично работает через метод преобразования. Почему он решает использовать только ctors, если я отбрасываюA
? - person Ari   schedule 27.05.2016