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:
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.
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.
No, template member functions cannot be virtual.
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.
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With