S
Steven T. Hatton
<quote
url="http://www.informit.com/guides/content.asp?g=cplusplus&seqNum=53&rl=1">
exported Templates
Last updated Sep 6, 2006.
exported Templates
The separate compilation model enables us to define functions, types and
objects in one translation unit and refer to them from other translation
units. After compiling all the translation units of a program, the linker
subsequently resolves all the references to extern symbols, producing a
single executable file. When dealing with ordinary functions and classes,
the separate compilation model works neatly.
Templates, however are a different beast. When you instantiate a template,
the compiler must see its definition. This is an explicit requirement in
the C++ standard, which states that dependent names (names that depend on
the type of a template parameter) shall be looked up in both the current
context (i.e., the place of instantiation) and the context of the
template's definition. The compiler cannot generate the code of a
specialization without looking at the template's definition ? even if the
definition appears in a separate translation unit. If the template is
defined in several source files, all the definitions must comply with the
One Definition Rule. As I explained elsewhere, the common approach is to
define the template in a header file and #include it in every source file
that uses that template.
If you have used templates before, you already know that. However, standard
C++ defines another compilation model for templates known as the separation
model.
export: How it All Began
Right from the start, C++ creators called for separate compilation of
templates. However, they didn't specify how this could be accomplished.
Unlike most other C++ features, which were standardized only after being
implemented by one vendor at least, exported templates were added to C++ in
1996 with no existing implementation whatsoever.
In 1996, many compilers hardly supported ordinary templates and the C++
community had gained little experience with advanced template techniques
such as meta-programming. Therefore, the implications of implementing
export weren't fully recognized. The very few people who have implemented
exported templates since agree that this is an arduous task indeed.
State of the Art
The most popular C++ compilers (Microsoft's Visual C++ .NET, Borland's C++
BuilderX, GNU's GCC and others) don't support export. Even vendors who have
expressed their commitment to "100% ISO compliance" exclude export from
their checklist. The frequently-cited reason for this is "lack of demand."
Could it be that users don't demand this features because they've never had
a chance to use it?
....
</quote>
One view of the "proper" use of "header files" is that they
represent "interfaces", whereas "source files" represent implementations.
Indeed some people suggest that we not have anything requiring allocation
in a header file; with the exception of (judiciously chosen) inline member
functions, and class template members[*]. That means, according to the
advice, MyClass::_data doesn't belong in a header.
class MyClass {
public:
std:stream& write(std:stream& out);
private:
std::string _data; //I don't belong here?
};
I have to agree that I gain a modest sense of accomplishment if I write a
class definition in a header file, and the only #include needed is to
include the definition of the base class. Any other types named can be
introduced using a forward declaration.
So what has this to do with `export'? Well, without it, all of a template
definition must go in a header file, or directly in the source file being
compiled. The motivations I am aware of for not wanting allocation defined
in a header are so that code compiled using the header won't need to be
recompiled if the implementation of the interface declared in the header
changes. Another reason is that it speeds up compile time. I'm not sure
any of that would be gained in the case of processing template code as a
direct result of implementing export. For example, would using precompiled
headers provide all the compile speed advantages that would be gained by
implementing export?
What would I gain if my compiler supported export?
[*]Of course we are also admonished not to "second guess" the implementors
of the (Standard) Library by forward declaring entities defined therein.
IOW I shouldn't try to forward declare std::string like this:
namespace std {
class string; //Wrong! Mere users should not mess with std::
}
url="http://www.informit.com/guides/content.asp?g=cplusplus&seqNum=53&rl=1">
exported Templates
Last updated Sep 6, 2006.
exported Templates
The separate compilation model enables us to define functions, types and
objects in one translation unit and refer to them from other translation
units. After compiling all the translation units of a program, the linker
subsequently resolves all the references to extern symbols, producing a
single executable file. When dealing with ordinary functions and classes,
the separate compilation model works neatly.
Templates, however are a different beast. When you instantiate a template,
the compiler must see its definition. This is an explicit requirement in
the C++ standard, which states that dependent names (names that depend on
the type of a template parameter) shall be looked up in both the current
context (i.e., the place of instantiation) and the context of the
template's definition. The compiler cannot generate the code of a
specialization without looking at the template's definition ? even if the
definition appears in a separate translation unit. If the template is
defined in several source files, all the definitions must comply with the
One Definition Rule. As I explained elsewhere, the common approach is to
define the template in a header file and #include it in every source file
that uses that template.
If you have used templates before, you already know that. However, standard
C++ defines another compilation model for templates known as the separation
model.
export: How it All Began
Right from the start, C++ creators called for separate compilation of
templates. However, they didn't specify how this could be accomplished.
Unlike most other C++ features, which were standardized only after being
implemented by one vendor at least, exported templates were added to C++ in
1996 with no existing implementation whatsoever.
In 1996, many compilers hardly supported ordinary templates and the C++
community had gained little experience with advanced template techniques
such as meta-programming. Therefore, the implications of implementing
export weren't fully recognized. The very few people who have implemented
exported templates since agree that this is an arduous task indeed.
State of the Art
The most popular C++ compilers (Microsoft's Visual C++ .NET, Borland's C++
BuilderX, GNU's GCC and others) don't support export. Even vendors who have
expressed their commitment to "100% ISO compliance" exclude export from
their checklist. The frequently-cited reason for this is "lack of demand."
Could it be that users don't demand this features because they've never had
a chance to use it?
....
</quote>
One view of the "proper" use of "header files" is that they
represent "interfaces", whereas "source files" represent implementations.
Indeed some people suggest that we not have anything requiring allocation
in a header file; with the exception of (judiciously chosen) inline member
functions, and class template members[*]. That means, according to the
advice, MyClass::_data doesn't belong in a header.
class MyClass {
public:
std:stream& write(std:stream& out);
private:
std::string _data; //I don't belong here?
};
I have to agree that I gain a modest sense of accomplishment if I write a
class definition in a header file, and the only #include needed is to
include the definition of the base class. Any other types named can be
introduced using a forward declaration.
So what has this to do with `export'? Well, without it, all of a template
definition must go in a header file, or directly in the source file being
compiled. The motivations I am aware of for not wanting allocation defined
in a header are so that code compiled using the header won't need to be
recompiled if the implementation of the interface declared in the header
changes. Another reason is that it speeds up compile time. I'm not sure
any of that would be gained in the case of processing template code as a
direct result of implementing export. For example, would using precompiled
headers provide all the compile speed advantages that would be gained by
implementing export?
What would I gain if my compiler supported export?
[*]Of course we are also admonished not to "second guess" the implementors
of the (Standard) Library by forward declaring entities defined therein.
IOW I shouldn't try to forward declare std::string like this:
namespace std {
class string; //Wrong! Mere users should not mess with std::
}