6

Consider the following code. Is it guaranteed that Derived<int>::foo() will be instantiated? foo() is virtual and is called by a non-virtual function of the base class.

#include <iostream>

class Base
{
public:
    void bar() { foo(); }
private:
    virtual void foo() = 0;
};

template <typename T> class Derived: public Base
{
public:
    Derived(T t_) : t(t_) {}
private:
    void foo() override { std::cout << t; }
    T t;
};

Derived<int> make_obj()
{
    return Derived<int>(7);
}
BlindDriver
  • 627
  • 3
  • 14
  • 1
    Thinking on my feet here. The template instantiation engine has no way of knowing for sure which `virtual` functions are used and which ones are not used. To be safe, it must instantiate all `virtual` functions. – R Sahu Dec 15 '16 at 22:23

2 Answers2

7

Standard section 14.7.1/11 says

It is unspecified whether or not an implementation implicitly instantiates a virtual member function of a class template if the virtual member function would not otherwise be instantiated.

However, for a typical vtable implementation, instantiating any constructor of the class requires a vtable for the class to exist, which must contain a pointer to the specialization's virtual function definition. So in practice the virtual function will probably be instantiated.

aschepler
  • 70,891
  • 9
  • 107
  • 161
  • 2
    I think this formulation gives just enough leeway for implementations that if they can optimize away the vtable, then they need not instantiate all otherwise unused virtual functions. The example given in the question gives such an optimization opportunity: There is no polymorphism involved. – j6t Dec 15 '16 at 22:29
0

Virtual table will always be instantiated for a class hierarchy, however, in your case it will be compiler dependent whether the foo gets actually initialized on a class creation since the class itself is initialized on a stack and never used polymorphocally. The virtual table will be meaningless in your case.

Ezra
  • 49
  • 4