Pergunta

Eu tenho uma classe C ++ modelo que é instanciado com 3 parâmetros de tipo diferentes. Há um método que as necessidades da classe para ter apenas um desses tipos e que não é sempre chamado com os outros dois tipos.

código objeto irá para esse método ser gerados três vezes (para todos os tipos para os quais o modelo é instanciado), ou é o código objeto gerado apenas uma vez (para o tipo com o qual ele é realmente usada)?

Foi útil?

Solução

funções membro virtuais são instanciado quando um modelo de classe é instanciado, mas as funções de membro não-virtuais são instanciado somente se eles são chamados.

Este é coberto em [temp.inst] no C ++ padrão (Em C ++ 11, este é §14.7.1 / 10. Em C ++ 14, é §14.7.1 / 11, e em C ++ 17 é §17.7.1 / 9. Extracto de C ++ 17 abaixo)

Uma implementação não deve instanciar implicitamente um modelo de função, um modelo variável, um membro modelo, uma função não-virtual membro, uma classe membro, um membro de dados estáticos de um modelo de classe, ou um subinstrução de um constexpr if (9.4.1), a menos que tal instanciação é necessária

Observe também que é possível instanciar um modelo de classe, mesmo se algumas das funções de membros não são instanciáveis ??para os parâmetros do modelo dado. Por exemplo:

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;
}

Isso é válido, embora Xyzzy :: CallFoo () não é instanciável porque não existe tal coisa como BarOnly :: foo (). Este recurso é usado frequentemente como uma ferramenta de modelo metaprogramming.

Note, no entanto, que "instanciação" de um modelo não diretamente correlato para a quantidade de código objeto é gerado. Isso vai depender de seu compilador implementação / vinculador.

Outras dicas

Eu acho que depende do compilador e configurações. Por exemplo, eu acredito MSVC6 gerado tudo, mas VS2005 não. A especificação diz o compilador não deveria, mas no mundo real, que depende do compilador real (há muitas soluções alternativas em impulso para MSVC6, por exemplo). O ligador pode remover funções não referenciadas se / opt: Ref. Estiver ativada (para VS, existem opções equivalentes para outros compiladores)

Normalmente, sim.

Todo o compilador realmente sabe é que seu programa pode criar pelo menos uma instância de cada classe. Mas não sei o que você vai fazer com essas instâncias. Assim, o código será quase certo ser gerado.

Dito isto, se os métodos em questão são não virtual, e nunca são chamados, a vinculador pode removê-los com as suas características de remoção de código morto normais. Assim, o código gerado (e compilados) não estará no EXE final.

Além disso, este dependerá em grande parte o compilador C ++ sendo usado, porque eles não são todos iguais.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top