Я бы не сказал, что он предпочитает столько, сколько требуется.

я есть классC у которого есть оператор приведения к чему угодно. В примере я попытался привести его кstd::string тремя разными способами:static_castконструкторstd::string и присваиваяstd::string, Однако компилируется только последний, в то время как другие вызывают ошибку неоднозначного конструктора.

Причина ошибки достаточно ясна: существует много способов конвертацииC к чему-то, что конструкторstd::string могу принять. Но в чем разница между этими случаями? Почему оператор приведения работает здесь, как задумано, а не там?

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: как упомянул в комментариях Болов, эта проблема не воспроизводится с C ++ 17. Я протестировал его с g ++ - 5 и clang-3.8 с -std = c ++ 11 и -std = c ++ 14, и он показывает описанные ошибки.

Ответы на вопрос(1)

Ваш ответ на вопрос