Why export templates would be useful in C++


Why would export templates be useful in C++?

export template

The C++ standard defines the concept of “export templates”. These are template classes and functions that are declared only where they are used (i.e. usually in a header file), while some are invoked only once in the compilation unit.

In other words, you can have a header file like this:

// the_header_file.hh
export template
void foo(const T& value);

And then you can use it somewhere like this:

#include "the_header_file.hh"

int main()
{
    foo(123);
    foo("456");
}

Notice how the calling code is inside main() don’t see how
foo() The template function is implemented, just like it is with regular templates. He only sees its announcement.

implementation of foo() Can then be placed into a source file to be compiled separately.

In practice this means that linker The compiler must be launched to compile instantiations of foo()
It is used for each type.

Myths about export templates

No, this is not an error in the title.

Whenever you see a discussion about export templates, you’ll definitely see some misconceptions about them. And There are also misconceptions about these templates themselves, especially in cases where one is arguing why export templates in the standard are actually unnecessary and useless overhead (and thus they should be removed from there).

Surely people (even expert C++ programmers and designers) will list this Wrong Why export templates are “useless” and should be removed from the standard. They will usually list misconceptions people have about export templates such as:

  • “Export templates allow hiding template implementations in pre-compiled closed-source proprietary libraries.”
  • “Export templates make compilation faster and object files smaller.”
  • etc…

Almost always, whether these arguments are actually true is a matter of argument (and will also depend on the actual implementation of export templates in the compiler). People advocating the removal of export templates from the C++ standard claim that all of these arguments are misconceptions and thus the export template feature is more or less useless.

Both types of people (those who may have misconceptions about export templates and those who argue against those misconceptions and promote the removal of export templates from the standard) are completely missing the most important point of export templates.

Export templates increase modularity

The most important feature of export templates is that they increase modularity and locality of template code. This is something that I have
Never These people were seen discussing.

This is something that should definitely not be taken lightly.

As an example of how export templates increase modularity, consider the following piece of code in some compilation unit:

namespace
{
    class SomeClass { /* ... */ };

    std::map someLocalMap;

    void performSomeLocalOperation() { /* some code here */ }
}

export template
void foo(const T& value)
{
    // some code that utilizes someLocalMap
    // and performSomeLocalOperation()
}

Note that in the above example SomeClass,
someLocalMap And performSomeLocalOperation() They are local to the compilation unit they reside in, and so are not visible nor accessible from anywhere else.

Also note that foo() The template function has access to them, by the simple fact that its implementation is located in the same compilation unit.

This is something that is not possible with regular non-exported templates. Non-exported templates are instantiated wherever they are used, and so they do not have access to a different compilation unit’s local data (there isn’t even a try syntax for them).

This is a very powerful modularity feature that should definitely not be taken lightly. Lack of export template creates template functions and classes inferior In this respect for regular functions and classes: they cannot have data that is local to their own compilation unit.

(Template classes may contain some kind of “local” data in the form of static members. However, this is not the same thing: each specific template instantiation of this class will have its own Different versions of these static members, different from others. They will not be shared by all template instantiations, as is data in a local compilation. This can be a hindrance in some cases, if not a complete showstopper.)

This is a very important thing that most of these people are missing. This is why export templates will be useful and important.

“Manual” export templates

Incidentally, there is a way to “manually” simulate exporting templates into a program (although this has its limitations), a fact that is surprisingly little known, even by expert C++ programmers. These “manual” export templates, if they can be used, can be quite useful and alleviate the modularity problems of regular templates in the same way that actual export templates do.

It is a surprisingly little known fact that the implementation of a template function or class is not actually mandatory with its declaration. You can doIn fact, write the code like this:

// main.cc
template
void foo(const T& value);

int main()
{
    foo(123);
}

This will not cause compiler errors. Its No is mandatory for
foo() Along with its announcement, implementation should also be provided. The above code is, effectively, a “initializing the declaration” of a foo() The function is taking a const int reference as a parameter.

Naturally if the above is your complete code, you will get a linker error because the linker cannot find its implementation. foo(),

If you apply it foo() template function somewhere else instantiate it with type intSo the program will actually link and work properly.

You can take advantage of this to apply a “manual” export template. In other words, templates that work exactly like export templates, the only relevant difference being that you have to manually instantiate the template for each type rather than the compiler doing it for you.

In the above example you might have another source file that contains, for example, the following code:

// foo.cc
#include 

template
void foo(const T& value)
{
    std::cout << value << std::endl;
}

template void foo(const int&); // Explicit instantiation

When you compile and link both the above source files, the compilation will be successful and the program will work as expected.

As you can see, the implementation of foo() appears within foo.cc is the source file and is not seen in any way or form by the code inside main.cc file, still it works. This is almost exactly how an export template would work.

Most importantly, foo.cc can contain local data inside an unnamed namespace, and foo() The function will be able to access it, just like an export template.

The exact same trick can be used with template classes. In this case it would be the class that requires an explicit instantiation for each used type (using the syntax “template class TheClass;,

Of course the limitation here is that every time you use a template function or class with a new type, you have to add a new explicit instance for that type in the source file where the template is implemented.

What export templates will do is to avoid doing this: The compiler will, effectively, automatically instantiate the template for each type so that you don’t have to do it manually yourself.

in conclusion

Templates are functions and classes inferior For regular functions and classes because templates cannot contain data that is local to their own compilation unit. (A template class can contain data that is local to the class, but this data will not be shared by different template instantiations of that class.) This reduces the modularity of the template.

Export template will solve this problem. Explicit instantiation of the template (“manual export template”) partially solves the problem, but it is an inconvenient and limited technique.

The C++ standard will probably make export templates obsolete or obsolete in the future (perhaps even with the next version of the standard). This decision is motivated only by the fact that compilers are not implementing this feature, not because there would be anything inherently wrong or flawed about exporting templates. In other words, compiler vendors and developers are setting the standard (“this is too laborious to implement”) rather than determining what will work best for programmer,

that’s a shame.

Many people argue that export templates are not useful at all, and all the potential benefits are just misconceptions, and thus there are no advantages as such, and so it is a good thing that they have been removed from the standard. that’s a lie. Export templates have significant advantages in terms of modularity (and, indeed, there are things that can be done with regular functions and classes that simply cannot be done with templated versions), and Only They will be removed from the standard because the compiler vendors consider them “too laborious to implement”, not because there would be anything inherently wrong with them from a programmer’s point of view.



Leave a Comment