Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The impact of virtual on the use of member of class template

I (vaguely) know that a template is not instantiated if it is not used. For example, the following code will compile fine even though T::type doesn't make sense when T = int.

template<typename T>
struct A
{
    void f() { using type = typename T::type; }
};

A<int> a; //ok

It compiles because f() is not used, so it is not instantiated — thus the validity ofT::type remains unchecked. It doesn't matter if some other member function g() calls f().

template<typename T>
struct A
{
    void f() { using type = typename T::type; }

    void g() { f(); } //Is f() still unused?
};

A<int> a; //ok

This also compile fines. But here I realize the vagueness in my understanding of the definition of "use". I ask:

  • Is f() still unused? How exactly?

I can clearly see it being used inside g(). But then I thought since g() is not used, f() is not used either, from instantiation point of view. That seems reasonable enough. so far.

However if I add virtual keyword to g(), it doesn't compile:

template<typename T>
struct A
{
    void f() { using type = typename T::type; }

    virtual void g() { f(); } //Now f() is used? How exactly?
};

A<int> a; //error

It results in compilation error because now it attempts to instantiate f(). I don't understand this behavior.

Could anybody explain this? Especially the impact of virtual keyword on the definition of "use" of member of class template.

like image 614
Nawaz Avatar asked Oct 28 '13 08:10

Nawaz


People also ask

Can a class member function template be virtual?

Member function templates can't be virtual functions. And, they can't override virtual functions from a base class when they're declared with the same name as a base class virtual function.

Can template be virtual method?

No, template member functions cannot be virtual.

What is a member template?

Unlike a member function for a template class, a template member function is just like a free template function but scoped to its containing class. In this case the compiler generates a member function for each (unique) template type. As before, the compiler will favour a non-template overload of a member function.

What is member function template in C++?

Member functions of class templates (C++ only) operator+('z') . The statement b + 4 is equivalent to b. operator+(4) . You can use trailing return types for template member functions, including those that have the following kinds of return types: Return types depending on the types of the function arguments.


1 Answers

A quick look at 3.2 [basic.def.odr] yields:

3/ [...] A virtual member function is odr-used if it is not pure. [...]

And I also found at 14.7.1 [temp.inst]:

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 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. (emphasis mine)

So... I would say it is likely that a virtual method will always be instantiated.

In pragmatic terms, I would expect a compiler to instantiate the virtual table of a template class when it instantiates the class; and thus immediately instantiate all virtual member functions of this class (so it can references those from the virtual table).

like image 52
Matthieu M. Avatar answered Oct 19 '22 07:10

Matthieu M.