Is a class with a template member function the same class?

I'm a little confused about the template member functions, suppose we have some weird structure with a template member function, like this:

struct Foo { template <typename T> void f(T t) {}; }; 

And then we save this structure in some standard container:

 std::vector<Foo> V; V.push_back(Foo()); V.push_back(Foo()); V.push_back(Foo()); V.push_back(Foo()); 

Further; let it call different instances of the template member function:

 V.at(0).f<int>(1); V.at(0).f<char>(2); V.at(1).f<float>(3.4f); V.at(2).f<double>(5.6); V.at(3).f<long>(7); 

And finally, the questions:

¿Do all instances of the class Foo belong to the same class? the answer seems to be yes, but ... the first instance of Foo has two overloads of the f member function at the end:

 [0] Foo::f(int t); [0] Foo::f(char t); 

And on the other hand, other instances of Foo seem to have only one version of f. Thus, the underlying type of each instance seems to be different due to differences in member functions.

 [1] Foo::f(float t); [2] Foo::f(double t); [3] Foo::f(long t); 

. If the functions f are given? , we can get the address of the function Foo :: f (int t) only from the first instance of Foo, because this function belongs only to this instance; same for other functions.

Thanks in advance.

+2
source share
4 answers

All overloads are generated by the compiler for the member function Foo::f , you can think of it as writing all of them manually.

Overload generation (instantiating a template) is not based on an instance, but rather on a class , the class itself receives all template instances (as all overloads of different types in the body of the class are written, for a given type T)

So this is in your case:

 struct Foo { template <typename T> void f(T t) {}; }; 

will become (conceptually)

 struct Foo { void f<int>(int t) {}; void f<char>(char t) {}; void f<float>(float t) {}; ... /// all the other uses of f with different types, anywhere in your code. }; 

This is one of the reasons why people argue about templates called code bloat.

+7
source

¿Do all instances of the class Foo belong to the same class? the answer seems to be yes

Yes, all instances are of the same type.

but ... the first instance of Foo has at the end two overloads of the f member function

Overloads are of type, not instance. The type will contain all overloads, regardless of which object the template instance was created.

¿Where are the functions f performed? apparently, we can get the address of the function Foo :: f (int t) only from the first instance of Foo, because this function belongs only to this instance; same for other functions.

They are created (compiled into binary code) by the compiler, where it is not the right question (except for binary). The address of a member function can only be obtained from a class, and not from any of the instances, as I already mentioned, member functions are a type-type, not an instance of a type.

+1
source

All Foo instances have all overloads, and they are all of the same type, since Foo itself is not a template class.

Functions are created at compile time in object code.

0
source

Let's look at another example:

 struct Foo { void f(int); void f(double); }; // ... Foo foo1, foo2; foo1.f(3); foo2.f(3.0); 

This is completely analogous to your own version, except that the compiler does not create new instances of the f() method. We call the f(int) method on foo1 , and we only call the f(double) method on foo2 . Do you think that they now have different types, just because we do not call all methods on each instance?

Methods are associated with classes, not instances. All methods of overloading your code generate methods of the Foo class, and all your instances are of the same type.

0
source

Source: https://habr.com/ru/post/974684/


All Articles