The meaning of the following template function?

#define Create_Function(Type) \ template void Function( std::vector<boost::shared_ptr<Type>>&) Create_Function(std::string); 

I saw the above code in legacy code, but have no idea what that means. This is not a regular definition of unspecialized functions, but a complete definition of a specialized function.

Any idea?

+4
source share
2 answers

It creates an explicit template instance (see MSDN )

Explicit instantiation allows you to instantiate a class or function template without actually using it in your code. Because it is useful when creating library files (.lib) that use templates for distribution, uninteresting template definitions do not fit into objects (.obj).

For a generic function template

 template<typename T> void Function( std::vector<boost::shared_ptr<T>>&) { // bla bla } 

The macro call Create_Function(std::string); will expand to

 template void Function( std::vector<boost::shared_ptr<std::string>>&); 
+4
source

This is an explicit creation of a function template. Given a pattern, for example:

 template <typename T> void Function( std::vector<boost::shared_ptr<T> >& ); 

(possibly declared in the header and defined in the .cpp file), the code:

 template void Function( std::vector<boost::shared_ptr<int> >& ); 

requires the compiler to create (generate code for) a specialization in this translation unit. This can be used to reduce compilation time, since template users will only need to see the template declaration and not create it in each translation unit where it is used. The bottom side requires that for each type used with this template, explicit instantiation is performed in the translation unit, which has access to the template definition, which limits the use of the template to these instances.

 // tmpl.h template <typename T> void Function( std::vector<boost::shared_ptr<T> >& ); // tmpl.cpp template <typename T> void Function( std::vector<boost::shared_ptr<T> >& p ) { ... } template void Function( std::vector<boost::shared_ptr<int> >& ); template void Function( std::vector<boost::shared_ptr<double> >& ); // user.cpp, user2.cpp, user3.cpp #include <tmpl.h> ... std::vector<boost::shared_ptr<int> > v; Function( v ); // [1] 

In this example, when compiling "user # .cpp" we do not incur the cost of creating a Function template in all translation units that use odr-use, only in 'tmpl.cpp', which potentially reduces compilation time.

Sometimes the reason for this approach is the downside, since you can effectively restrict instance types to the subset for which you provided an explicit instantiation (ie, in the code above, if "userN.cpp" tried to call Function passing a vector of common pointers to std::string , the linker will complain).

Finally, in some cases, I saw this as a way to hide the actual implementation of the template from library users, when the set of types for which it can be used is limited.

+3
source

All Articles