eap
eap

Reputation: 188

C++ template static class code generation

Suppose I have a template static class in a "Foo.h" file like following:

template<typename T> class Foo
{
    public:
        static T foo1();
        static T foo2();
        static T foo3();
        static T foo4();
        static T foo5();
};

// definitions...

Now, suppose I have a "main.cpp" file like this:

#include "Foo.h"
main()
{
    double value = Foo<double>::foo3();

    // Do something with value

    return 0;
}

When I compile this file, will the methods foo1(), foo2(), foo4(), and foo5() be also there in the generated code?

Upvotes: 0

Views: 173

Answers (4)

gwiazdorrr
gwiazdorrr

Reputation: 6329

No.

C++ Standard 14.7.1/10

An implementation shall not implicitly instantiate a function template, a member template, a non-virtual member function, a member class, or a static data member of a class template that does not require instantiation. (...)

It is an extremely useful technique, especially combined with policy based design. You can basically define member functions that only work for some template parameters; if you don't use them in such cases you won't get a compile error.

Upvotes: 3

Mike Seymour
Mike Seymour

Reputation: 254461

No, only foo3 will be instantiated. Member functions of a class template are treated as separate templates, and each is only instantiated if it's used (or explicitly instantiated).

You can see this yourself by putting code in one of the unused functions which wouldn't compile when instantiated with double, like

static T foo1() {return T().nonsense;}  // double has no members

Your code, which only uses foo3, will still compile since it won't try to instantiate this.

Upvotes: 2

aschepler
aschepler

Reputation: 72311

No.

C++ 14.7.1/1-2, emphasis mine:

The implicit instantiation of a class template specialization causes the implicit instantiation of the declarations, but not of the definitions or default arguments, of the class member functions, member classes, scoped member enumerations, static data members and member templates; and it causes the implicit instantiation of the definitions of unscoped member enumerations and member anonymous unions.

Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist....

So your example would even be correct if for example plugging in double for the definition double Foo<double>::foo1() would cause an error.

On the other hand, if you used an explicit instantiation of the class:

template class Foo<double>;

then all members are instantiated.

Upvotes: 2

Olaf Dietsche
Olaf Dietsche

Reputation: 74028

This is easily tested. When I put your code in a file and compile it with gcc

g++ -g a.cpp

I get a binary a.out. Now I can look into it with nm

nm a.out | grep foo

which gives

00000000004004dc W _ZN3FooIdE4foo3Ev

So, no foo1 or any other beside foo3

Upvotes: 0

Related Questions