Comportamento diferente entre elenco explícito, inicialização direta e inicialização de cópia

Eu tenho aulaC que tem um operador de casting para qualquer coisa. No exemplo, tentei lançar uma instância dele parastd::string de três maneiras diferentes:static_castconstrutor destd::string e atribuindo astd::string. No entanto, apenas o último compila, enquanto os outros geram um erro de construtor ambíguo.

A razão do erro é clara o suficiente: existem muitas maneiras de converterC para algo que o construtor destd::string pode aceitar. Mas qual é a diferença entre esses casos? Por que o operador de elenco funciona como pretendido aqui, mas não lá?

struct C {
    template<typename T>
    operator T() const {
        return T{};
    }
};

int main() {
    C c;

    cout << static_cast<string>(c) << endl; // compile error
    string bad(c); // compile error
    string ok = c; // compiles successfully
}

UPD: como bolov mencionado nos comentários, esse problema não se reproduz no C ++ 17. Eu testei com g ++ - 5 e clang-3.8 com -std = c ++ 11 e -std = c ++ 14, e mostra os erros descritos.

questionAnswers(1)

yourAnswerToTheQuestion