Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why uncalled template class members *parameters* ARE instantiated?

This question is a counterpoint to: Why uncalled template class members aren't instantiated?, where the author was surprised that some template methods weren't instantiated.

I have the opposite problem: parts of my function are getting instantiated when I don't expect them to. Take the following program:

template <class T> class Foo;

template <class T>
class Bar {
  template <class U> void Baz(typename Foo<T>::X x) {}
};

int main() {
  Bar<int> bar;
}

This program fails to compile with the error:

test.cc:6:40: error: implicit instantiation of undefined template 'Foo<int>'
  template <class U> void Baz(typename Foo<T>::X x) {}
                                       ^
test.cc:10:12: note: in instantiation of template class 'Bar<int>' requested here
  Bar<int> bar;
           ^
test.cc:2:26: note: template is declared here
template <class T> class Foo;

But why is it trying to instantiate a parameter of a function I haven't called? It's a template function with a template parameter that it cannot know, which makes it doubly weird that it instantiates the function argument type.

Why does it do this? And why does SFINAE not help me here, and at worst remove the overload from consideration?

like image 421
Josh Haberman Avatar asked Oct 20 '22 21:10

Josh Haberman


1 Answers

When you create an instance of a template class, the class needs to be fully defined. This includes the member function declarations. If one of the member function declarations are not fully defined, then the class itself is not fully defined.

In this case, there's no definition for Foo<T>::X so the Baz function can not be fully declared, and the class as a whole is not fully defined.

like image 188
Some programmer dude Avatar answered Dec 02 '22 23:12

Some programmer dude