Linking an explicit instance of a class

Are multiple instances of the same type of template of the same type valid in different compilation units? What about function templates?

Sample code is as follows:

test.hpp

template <typename T> class A { public: T out(); }; template <typename T> T A<T>::out() { return T(1); } 

test1.cpp

 #include "test.hpp" template class A<int>; int testFn() { return A<int>().out(); } 

test2.cpp

 #include "test.hpp" template class A<int>; extern int testFn(); int main() { return testFn() == A<int>().out(); } 

If I run

 g++ -std=c++11 test1.cpp test2.cpp -o test 

it compiles without complaint about duplicate definitions.

I referred to the old drafts of the standard [1] [2], and suggesting that part of the connection does not change too much (with the exception of anonymous namespaces). The class template has external communication at 3.5p4 and 14p4. In this case, I would expect g ++ to complain about duplicate definitions of A :: out (). Did I miss something?

What if test.hpp defines a function template without "static" or "inline"?

Thanks.

[1] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2798.pdf [2] http://www.open-std.org/jtc1/sc22/wg21 /docs/papers/2012/n3337.pdf

+8
c ++ c ++ 11 templates linkage
source share
1 answer

A good way to find answers to these questions in an implementation is to use "nm". Often garbled C ++ characters are more readable if you pass output from nm to C ++ filt.

For example, if you compiled with ā€œ-cā€ to create ā€œ.oā€ for each compilation unit, you can run nm. When I do this, I see that the members of the template are weak characters of the "W" code (on x86 linux). This means that several definitions are in order and in a specific system. If I create a function that is not templatized, it will display as "T" in both translation units of the corresponding object files. This will cause a few specific characters.

Typically, C ++ templates are created as needed (without a full copy), which will allow you to use a header like _impl in addition to the header of the declaration.

You are not allowed to define a member template as static (which will give an error). You can define it as inline. In this case, you will not see the symbol for the member template using nm, because it was embedded.

+1
source share

All Articles