tipos resueltos programacion poo plantillas orientada objetos ejercicios ejemplos ejemplo codigo clases c++ templates footprint

resueltos - programacion orientada a objetos c++ ejemplos



¿Se genera código objeto para los métodos de clase de plantilla no utilizados? (3)

Tengo una clase de plantilla C ++ que se crea una instancia con 3 parámetros de tipo diferentes. Hay un método que la clase necesita tener solo para uno de esos tipos y que nunca se llama con los otros dos tipos.

¿Se generará el código de objeto para ese método tres veces (para todos los tipos para los que se crea una instancia de la plantilla), o se generará el código objeto una sola vez (para el tipo con el que se usa realmente)?


Creo que depende del compilador y la configuración. Por ejemplo, creo que MSVC6 generó todo, pero VS2005 no lo hace. La especificación dice que el compilador no debería, pero en el mundo real, depende del compilador real (hay muchas soluciones alternativas para MSVC6, por ejemplo). El enlazador puede eliminar funciones sin referencia si / opt: ref está habilitado (para VS, existen opciones equivalentes para otros compiladores).


Por lo general, sí.

Todo lo que el compilador realmente sabe es que su programa puede crear al menos una instancia de cada clase. Pero no sabe qué hará con esas instancias. Por lo tanto, se generará casi seguro el código.

Dicho esto, si los métodos en cuestión no son virtuales y nunca se llaman, el enlazador puede eliminarlos con sus características normales de eliminación de código inactivo. Por lo tanto, el código generado (y compilado) no estará en el EXE final.

Además, esto dependerá en gran medida del compilador de C ++ que se utilice, ya que no son todos iguales.


Las funciones de miembros virtuales se crean instancias cuando se crea una instancia de una plantilla de clase, pero las funciones de miembros no virtuales se instancian solo si se invocan.

Esto está cubierto en [temp.inst] en el estándar C ++ (En C ++ 11, esto es §14.7.1 / 10. En C ++ 14, es §14.7.1 / 11, y en C ++ 17 es §17.7.1 / 9. Extracto de C ++ 17 a continuación)

Una implementación no instanciará implícitamente una plantilla de función, una plantilla de variable, una plantilla de miembro, una función de miembro no virtual, una clase de miembro, un miembro de datos estáticos de una plantilla de clase, o una subestación de una declaración constexpr if (9.4.1 ), a menos que se requiera tal ejemplificación

También tenga en cuenta que es posible instanciar una plantilla de clase incluso si algunas de las funciones miembro no son instanciables para los parámetros de plantilla dados. Por ejemplo:

template <class T> class Xyzzy { public: void CallFoo() { t.foo(); } // Invoke T::foo() void CallBar() { t.bar(); } // Invoke T::bar() private: T t; }; class FooBar { public: void foo() { ... } void bar() { ... } }; class BarOnly { public: void bar() { ... } }; int main(int argc, const char** argv) { Xyzzy<FooBar> foobar; // Xyzzy<FooBar> is instantiated Xyzzy<BarOnly> baronly; // Xyzzy<BarOnly> is instantiated foobar.CallFoo(); // Calls FooBar::foo() foobar.CallBar(); // Calls FooBar::bar() baronly.CallBar(); // Calls BarOnly::bar() return 0; }

Esto es válido, aunque Xyzzy :: CallFoo () no es instanciable porque no existe BarOnly :: foo (). Esta característica se usa a menudo como una herramienta de metaprogramación de plantillas.

Sin embargo, tenga en cuenta que la "instanciación" de una plantilla no se correlaciona directamente con la cantidad de código objeto que se genera. Eso dependerá de su implementación de compilador / enlazador.