¿Por qué no funciona una clase con un operador de conversión para std :: string?

Esto funciona, imprimiendo 1.:

#include <iostream>

struct Int {
    int i;
    operator int() const noexcept {return i;}
};

int main() {
    Int i;
    i.i = 1;
    std::cout << i;
}

Sin embargo,esto no se compila en GCC 4.8.1:

#include <iostream>
#include <string>

struct String {
    std::string s;
    operator std::string() const {return s;}
};

int main() {
    String s;
    s.s = "hi";
    std::cout << s;
}

Aquí están las partes relevantes del error:

error: no hay coincidencia para ‘operador <<’ (los tipos de operandos son ‘std :: ostream {aka std :: basic_ostream}’ y ‘String’)
std :: cout << s;

recorte

template std :: basic_ostream <_CharT, _Traits> & std :: operator << (std :: basic_ostream <_CharT, _Traits> &, const std :: basic_string <_CharT, _Traits, _Alloc> &)
operador << (basic_ostream <_CharT, _Traits> & __os,

/usr/include/c++/4.8/bits/basic_string.h:2753:5: nota: la sustitución / sustitución de argumentos de la plantilla ha fallado:
main.cpp: 25: 18: nota: 'String' no se deriva de 'const std :: basic_string <_CharT, _Traits, _Alloc> ’
std :: cout << s;

Solo usostd::cout ystd::string, que tienen los mismos argumentos de plantilla. Realmente no estoy seguro de por qué esto no podría recoger la conversión implícita como lo hizo paraInt. ¿Por qué funciona conint, pero nostd::string?

Respuestas a la pregunta(2)

Su respuesta a la pregunta