Explicit instantiation - when is it used?

2019-01-01 05:41发布

After few weeks break, I'm trying to expand and extend my knowlege of templates with the book Templates – The Complete Guide by David Vandevoorde and Nicolai M. Josuttis, and what I'm trying to understand at this moment is explicit instantiation of templates.

I don't actually have a problem with the mechanism as such, but I can't imagine a situation in which I would like or want to use this feature. If anyone can explain that to me I will be more than grateful.

标签: c++ templates
3条回答
妖精总统
2楼-- · 2019-01-01 06:04

Directly copied from https://docs.microsoft.com/en-us/cpp/cpp/explicit-instantiation:

You can use explicit instantiation to create an instantiation of a templated class or function without actually using it in your code. Because this is useful when you are creating library (.lib) files that use templates for distribution, uninstantiated template definitions are not put into object (.obj) files.

(For instance, libstdc++ contains the explicit instantiation of std::basic_string<char,char_traits<char>,allocator<char> > (which is std::string) so every time you use functions of std::string, the same function code doesn't need to be copied to objects. The compiler only need to refer (link) those to libstdc++.)

查看更多
萌妹纸的霸气范
3楼-- · 2019-01-01 06:22

It depends on the compiler model - apparently there is the Borland model and the CFront model. And then it depends also on your intention - if your are writing a library, you might (as alluded above) explicitly instantiate the specializations you want.

The GNU c++ page discusses the models here https://gcc.gnu.org/onlinedocs/gcc-4.5.2/gcc/Template-Instantiation.html.

查看更多
闭嘴吧你
4楼-- · 2019-01-01 06:26

If you define a template class that you only want to work for a couple of explicit types.

Put the template declaration in the header file just like a normal class.

Put the template definition in a source file just like a normal class.

Then, at the end of the source file, explicitly instantiate only the version you want to be available.

Silly example:

// StringAdapter.h
template<typename T>
class StringAdapter
{
     public:
         StringAdapter(T* data);
         void doAdapterStuff();
     private:
         std::basic_string<T> m_data;
};
typedef StringAdapter<char>    StrAdapter;
typedef StringAdapter<wchar_t> WStrAdapter;

Source:

// StringAdapter.cpp
#include "StringAdapter.h"

template<typename T>
StringAdapter<T>::StringAdapter(T* data)
    :m_data(data)
{}

template<typename T>
void StringAdapter<T>::doAdapterStuff()
{
    /* Manipulate a string */
}

// Explicitly instantiate only the classes you want to be defined.
// In this case I only want the template to work with characters but
// I want to support both char and wchar_t with the same code.
template class StringAdapter<char>;
template class StringAdapter<wchar_t>;

Main

#include "StringAdapter.h"

// Note: Main can not see the definition of the template from here (just the declaration)
//       So it relies on the explicit instantiation to make sure it links.
int main()
{
  StrAdapter  x("hi There");
  x.doAdapterStuff();
}
查看更多
登录 后发表回答