1

A class template is implicitly instantiated only when its definition is required:

https://stackoverflow.com/a/7731106/14196177 https://en.cppreference.com/w/cpp/language/class_template#Implicit_instantiation

However, if a template class instance is passed to a function, the instance's template argument gets instantiated, even though it's not used in any way. If the template argument is a template class specialization that contains invalid code for its template argument, an unnecessary compilation error occurs.

struct Abstract { virtual void pure() = 0; };

template<class Type> struct Invalid { Type Member; };

template<class> struct Example { void foo() {} };

template<class Type> void Test(Type&&) {}


int main()
{
    Example<Invalid<Abstract>> Object;
    Object.foo(); // No problem.
    Test(Object); // Error because of Invalid<Abstract>::Member.
    return 0;
}

Interestingly, there is no error if the template argument class Invalid is an incomplete type, that is, if it's not defined at all.

Why does an unused template argument type get instantiated when an instance of the template class is passed to a function? How to avoid such instantiation?

  • 1
    wrapping Test seems to remove the error ```struct S { template static void Test(Type&&) {} }; S::Test(Object);``` – B.D Nov 19 '21 at 00:46
  • 1
    wrapping Test with a namespace seem to work too but only if its not directed – B.D Nov 19 '21 at 00:58
  • 1
    @B.D Indeed! I found out that the function can be global, but just needs to be qualified with the scope operator: `::Test(Object)`. So it seems that this instantiation occurs when the function is called with an unqualified name. The question remains why. – Radoslav Voydanovich Nov 19 '21 at 11:47

0 Answers0