std::basic_iostiene un constructor público :
explicit basic_ios (std::basic_streambuf<CharT,Traits>* sb);
En mi opinión, la única razón para que una clase tenga un constructor público es usar una instancia independiente de esa clase en un programa. Si una clase existe solo para que otras clases desciendan de ella (como parece ser el caso basic_ios), todos los constructores de la clase deberían estarlo protected. Los constructores de std::ios_baseestán todos protegidos. Pero, por alguna razón, los diseñadores del estándar hicieron de éste un constructor de basic_iospúblico.
basic_iosse usa como una clase base para varios tipos de flujo, y no puedo imaginar un caso de uso en el que tenga uno que no sea al menos un basic_istreamo basic_ostream. ¿Hay uno?
fuente

basic_iostoma de un ctorbasic_streambuf*ha sido pública desde antes de que pudieras hacerlousing B::B;. Espero que las implementaciones antiguas solo tuvieran un ctor proxy:A(int x) : B(x) {}- que funciona bien incluso siBel ctor lo esprotected.Lo que no noté fue eso
std::basic_istream,std::basic_ostreamystd::basic_iostreamtambién tenía constructores públicos (cada uno toma unstd::basic_streambuf*).Esto permite un análogo de programación genérica de polimorfismo, en la misma línea que el idioma de pimpl.
Es decir, de esta manera puede crear un tipo de flujo de flujo especializado y usarlo en un
basic_[io]streamsin tener que crear clases de flujo especializadas. (La funcionalidad es limitada: no puede asignar un nuevo búfer a la misma secuencia, y debe realizar un seguimiento externo de la vida útil y la propiedad del búfer).Los
basic_[io]fstreamybasic_[io] especializadosstringstreamcontienen una instancia completa del tipo de búfer asociado. Esto significa que una instancia de un tipo de flujo especializado solo funcionará con su búfer interno y no otro, ni siquiera uno del mismo tipo. Usar unbasic_[io] sin formatostreames una solución (torpe) para esto.fuente