Why export templates would be useful

J

Juha Nieminen

Many people argue that there is *no* advantage in using export
templates other than the questionable advantage of being able to
separate the declaration from the implementation (which these people
seem to argue is only a purely cosmetic feature).

However, I have *never* seen discussed the absolutely *major*
advantage of export templates: That they have their own compilation
unit, which means that they have access to their own file-local scope
(which in turn can be used to increase the modularity of the program).
This is something which is just not possible with regular templates.

For that reason I have argued that template classes and functions
are actually *inferior* to regular classes and functions because the
former cannot have file-local scope while the latter can. Export
templates would solve this deficiency.

I have been thinking about what would be the simplest example which
is implementable with export templates and which isn't with regular
templates (at least not without global namespace contamination). How
about this:

//---------------------------------------------------
// MyClass.hh
export template<typename T>
class MyClass
{
public:
MyClass();
// other member functions here...
};
//---------------------------------------------------

//---------------------------------------------------
// MyClass.cc
namespace
{
unsigned constructorCallCounter = 0;
}

template<typename T>
MyClass<T>::MyClass()
{
++constructorCallCounter;
}
//---------------------------------------------------

You *could* achieve the same effect with regular templates, but
it would require adding a new name to global scope (accessible from
anywhere). This may not be a very viable solution if the amount of
stuff inside the nameless namespace above is large, nor is it very
good design.

(And no, making 'constructorCallCounter' a static member of
MyClass is *not* the same thing because it would mean that every
distinct template instantiation would have its own separate
'constructorCallCounter', rather than it being shared among all
of them.)

Can anyone come up with some objections to the example above?
(Note that the example is not intended to be an example of actual
usage, but instead the simplest possible example that demonstrates
the issue.)
 
A

Alf P. Steinbach

* Juha Nieminen:
Many people argue that there is *no* advantage in using export
templates other than the questionable advantage of being able to
separate the declaration from the implementation (which these people
seem to argue is only a purely cosmetic feature).

However, I have *never* seen discussed the absolutely *major*
advantage of export templates: That they have their own compilation
unit, which means that they have access to their own file-local scope
(which in turn can be used to increase the modularity of the program).
This is something which is just not possible with regular templates.

For that reason I have argued that template classes and functions
are actually *inferior* to regular classes and functions because the
former cannot have file-local scope while the latter can. Export
templates would solve this deficiency.

I have been thinking about what would be the simplest example which
is implementable with export templates and which isn't with regular
templates (at least not without global namespace contamination). How
about this:

//---------------------------------------------------
// MyClass.hh
export template<typename T>
class MyClass
{
public:
MyClass();
// other member functions here...
};
//---------------------------------------------------

//---------------------------------------------------
// MyClass.cc
namespace
{
unsigned constructorCallCounter = 0;
}

template<typename T>
MyClass<T>::MyClass()
{
++constructorCallCounter;
}
//---------------------------------------------------

You *could* achieve the same effect with regular templates, but
it would require adding a new name to global scope (accessible from
anywhere). This may not be a very viable solution if the amount of
stuff inside the nameless namespace above is large, nor is it very
good design.

(And no, making 'constructorCallCounter' a static member of
MyClass is *not* the same thing because it would mean that every
distinct template instantiation would have its own separate
'constructorCallCounter', rather than it being shared among all
of them.)

Can anyone come up with some objections to the example above?
(Note that the example is not intended to be an example of actual
usage, but instead the simplest possible example that demonstrates
the issue.)

There are a number of ways to design this functionality without exported templates.

The simplest is to just inherit from a constructor call counting class.

This preserves the property of the counter only being accessible from the
template code.

But it introduces one name in the public namespace.

If you want to avoid even that then you can put the whole shebang in a namespace
or outer class.


Cheers & hth.,

- Alf
 
J

Juha Nieminen

Alf P. Steinbach said:
The simplest is to just inherit from a constructor call counting class.

This preserves the property of the counter only being accessible from the
template code.

How do you stop other code from inheriting from the same class, hence
messing up with the counter (or whatever data is being handled)?

Also it doesn't help if what is modifying the file-local data is a
template function rather than a template class.
If you want to avoid even that then you can put the whole shebang in a
namespace or outer class.

A namespace still introduces a new name to global scope and doesn't
stop outside code from accessing the file-local data.
 
A

Alf P. Steinbach

* Juha Nieminen:
How do you stop other code from inheriting from the same class, hence
messing up with the counter (or whatever data is being handled)?

Also it doesn't help if what is modifying the file-local data is a
template function rather than a template class.


A namespace still introduces a new name to global scope and doesn't
stop outside code from accessing the file-local data.

I'm sure you can come with solutions to those new problems.

Cheers & hth.,

- Alf
 
J

Juha Nieminen

Pete Becker said:
While this discussion might be interesting on a theoretical level, note
that export templates have been removed from C++0x.

Which is a real shame. The standardization committee is not removing
export templates because they would be useless (as some people like to
claim, even though it's basically a lie) or because they wouldn't
benefit the programmer. They are removing them only and exclusively
because compiler writers deem them too laborious to implement. That's it.
The sole reason.

Some people argue that export templates have no advantages whatsoever.
This is a huge lie. I have *never* seen these people talking about the
issue of template classes and functions not having local scope, while
regular classes and functions, as well as export templates do. It's like
they are cherry-picking and choosing only those alleged advantages which
people think export templates have but which are not very relevant.

The lack of export templates can be a huge hindrance. I have personal
experience of this in an actual project. I have had to kludge my way
around this deficiency by using manual explicit template instantiation
(which kind of simulates export templates). While this works, it's a
cumbersome and limited technique.

The fact is that template functions and classes are inferior to regular
functions and classes because of this. Lack of export is a hindrance to
modularity. What *really* irritates me is the reason why they will be
removed from the standard: Because compiler writers can't be bothered
to implement it.
 
B

Balog Pal

Juha Nieminen said:
Which is a real shame. The standardization committee is not removing
export templates because they would be useless (as some people like to
claim, even though it's basically a lie) or because they wouldn't
benefit the programmer. They are removing them only and exclusively
because compiler writers deem them too laborious to implement. That's it.
The sole reason.

What more reason do you need? You can standardize free beer, but it will
jsut make the paper worthless.

The original intent of standards was to describe proven vorking practice
from the field anyway. Export made it in by a wild slip in the first place,
now only the situation is rectified.
Some people argue that export templates have no advantages whatsoever.
This is a huge lie.

I read a bunch of discussion, can't recall such a claim from anyone. Any
feature have some advantage. But it is not enough.
I have *never* seen these people talking about the
issue of template classes and functions not having local scope,

It is rarely mentioned. Guess because we don't use that many template
libraries to have realistic name clash on a namespace name picked as
"private" for the template stuff. That is just a little worse than the file
scope, so i don;'t get the fuss either.

While forcing inclusion of the implementation -- and all the #includes that
require is a real pain in the ass.
The fact is that template functions and classes are inferior to regular
functions and classes because of this. Lack of export is a hindrance to
modularity.

Well, on that very reasoning people pointed out that it is not 'export
templates' the root problem, but poor support for modules. That can be
addressed, with some straight effort.
What *really* irritates me is the reason why they will be
removed from the standard: Because compiler writers can't be bothered
to implement it.

That is a strange attitude -- no one forbids you to write an implementation
and make it publicly usable. If anyone did that, there would be no problem.
 
J

James Kanze

What more reason do you need? You can standardize free beer,
but it will jsut make the paper worthless.
The original intent of standards was to describe proven
vorking practice from the field anyway. Export made it in by a
wild slip in the first place, now only the situation is
rectified.

That's true, but it had a lot of company. Things like two
phased lookup, or a completely new, templated iostream.
 
R

Robert Fendt

They have? Indeed they have:

http://herbsutter.com/2010/03/13/trip-report-march-2010-iso-c-standards-meeting/

Good riddens.
Which is a real shame. The standardization committee is not removing
export templates because they would be useless (as some people like to
claim, even though it's basically a lie) or because they wouldn't
benefit the programmer. They are removing them only and exclusively
because compiler writers deem them too laborious to implement. That's it.
The sole reason.

That's actually a very, very good reason. An element of the
standard that has not been supported by popular compilers for
over a decade now, and about which writers of said popular
compilers have repeatedly stated that they won't ever implement
it, is in fact more harmful than advantageous.

Apart from that, your statement sounds like "the compiler makers
are just lazy". Quite an arrogant position, don't you think? I
do not claim to have the abilities or knowledge to properly
assess the complexity of a feature like 'export', but I am quite
sure people like Herb Sutter do. So I do what I consider to be a
sign of intelligence: "know when to shut up".

If you want the reasons why more or less nobody in the compiler
business likes 'export' be put a bit more eloquently and by a
guy who really knows his stuff, may I recommend this text:

Herb Sutter: "Why We Can't Afford Export"
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1426.pdf)

To sum it up for you, virtually no compiler maker thought export
would be a good idea. To date, there is exactly 1 (read: ONE)
working implementation by the Edison Design Group who (to quote
Sutter) 'are widely acknowledged to be among (or "the") world's
best C++ compiler writers'. Note that this is said by a
Microsoft guy about the competition.

Consider also the following points:

(1) Sutter notes that EDG found the implementation of 'export'
to be very hard (i.e., not really worth the effort).

(2) Add to it that people are confused to this day about what
export can and cannot do, and EDG even fears that potential
users will regard their implementation as inferior because of
those misunderstandings.

(3) EDG were among those that were against 'export' from the
start, and only implemented it because of the ambition to
provide a fully standard-compliant compiler frontend.

(4) All the other compiler makers, most noticeably the teams of
popular compilers like GCC and Visual C++, have considered
'export' and rejected it.

(5) EDG, being the only company who ever pulled off implementing
'export', still voted in favour of removing 'export' from C++
0x-- despite the investments they have made to implement it in the
first place. Which is quite a statement in its own right and
also the main reason it was actually removed.

That said, nobody prevents you from writing an implementation of
export. GCC is open source, just go for it. I wish you luck.

Regards,
Robert
 
J

Jerry Coffin

[ ... ]
Some people argue that export templates have no advantages
whatsoever. This is a huge lie. I have *never* seen these people
talking about the issue of template classes and functions not
having local scope, while regular classes and functions, as well as
export templates do. It's like they are cherry-picking and choosing
only those alleged advantages which people think export templates
have but which are not very relevant.

While you're right that exported templates could sometimes provide
some benefit, the benefit really was fairly minimal and the cost
really was quite high. Worse, I believe their presence in the
standard tended to stall (if not outright prevent) work on anything
better. As such, removing export from the standard is almost
certainly for the best, because it'll allow something better to be
designed and put into use.
 
A

Alf P. Steinbach

* Jerry Coffin:
[ ... ]
Some people argue that export templates have no advantages
whatsoever. This is a huge lie. I have *never* seen these people
talking about the issue of template classes and functions not
having local scope, while regular classes and functions, as well as
export templates do. It's like they are cherry-picking and choosing
only those alleged advantages which people think export templates
have but which are not very relevant.

While you're right that exported templates could sometimes provide
some benefit, the benefit really was fairly minimal and the cost
really was quite high. Worse, I believe their presence in the
standard tended to stall (if not outright prevent) work on anything
better.

In particular, modules. As I understand it.

As such, removing export from the standard is almost
certainly for the best, because it'll allow something better to be
designed and put into use.


Hopefully. :)


Cheers,

- Alf
 
B

Brian

  Many people argue that there is *no* advantage in using export
templates other than the questionable advantage of being able to
separate the declaration from the implementation (which these people
seem to argue is only a purely cosmetic feature).

  However, I have *never* seen discussed the absolutely *major*
advantage of export templates: That they have their own compilation
unit, which means that they have access to their own file-local scope
(which in turn can be used to increase the modularity of the program).
This is something which is just not possible with regular templates.

  For that reason I have argued that template classes and functions
are actually *inferior* to regular classes and functions because the
former cannot have file-local scope while the latter can. Export
templates would solve this deficiency.

  I have been thinking about what would be the simplest example which
is implementable with export templates and which isn't with regular
templates (at least not without global namespace contamination). How
about this:

//---------------------------------------------------
// MyClass.hh
export template<typename T>
class MyClass
{
 public:
    MyClass();
    // other member functions here...};

//---------------------------------------------------

//---------------------------------------------------
// MyClass.cc
namespace
{
    unsigned constructorCallCounter = 0;

}

template<typename T>
MyClass<T>::MyClass()
{
    ++constructorCallCounter;}

//---------------------------------------------------

  You *could* achieve the same effect with regular templates, but
it would require adding a new name to global scope (accessible from
anywhere). This may not be a very viable solution if the amount of
stuff inside the nameless namespace above is large, nor is it very
good design.

  (And no, making 'constructorCallCounter' a static member of
MyClass is *not* the same thing because it would mean that every
distinct template instantiation would have its own separate
'constructorCallCounter', rather than it being shared among all
of them.)

  Can anyone come up with some objections to the example above?
(Note that the example is not intended to be an example of actual
usage, but instead the simplest possible example that demonstrates
the issue.)


A few months ago I was asking a question in this thread:

http://groups.google.com/group/comp...cef87?lnk=gst&q="brian+wood"#9eb84e0cb88cef87


Here's a paragraph from that thread:

"In the past we added an option that allows users to
specify whether they want the code in header-only
(integrated) form or as two separate files. This was
in part because of some comments made by Kanze about
build times I think. Any thoughts on how to reconcile
this template use with that support? I'm not sure if
it's possible to keep supporting the separate header
and implementation approach with these changes."


Basically after deciding I needed to use class templates,
I was no longer able to support separated header and
implementation files. I asked if anyone had advice
on that, but didn't get a reply. I wondered if export
was the answer, but am not sure. Anyway, if exported
templates would help in that regard, they would be important
from a build perspective.


Brian Wood
http://webEbenezer.net
(651) 251-9384
 
A

Alf P. Steinbach

* Juha Nieminen:
Which is *exactly* what I'm talking about.

See how many times he mentions the issue of regular templates not
having a private compilation unit with file-local data, which makes them
inferior to regular functions/classes as well as export templates which
do. I'll wait.

On the contrary, see for example the section named "Potential Benefits
of Export", and see if you can find any reference whatsoever to export
templates having file-local data. I'll save you the trouble: He
conveniently skips that tidbit.

Moreover, he writes things like "A subtle but important distinction
to keep in mind is that the inclusion and export models really are
different source code organization models. They’re about massaging and
organizing your source code. They are not different instantiation
models; this means that a compiler must do essentially the same work to
instantiate templates under either source model,
inclusion or export."

Basically he is claiming that the only thing that export templates
allow is reorganizing your code. This is BS. He conveniently doesn't
make any mention about file-local scopes and how regular templates don't
have one, which makes them inferior to export templates.

I have the feeling that he does this on purpose.

He he, the great conspiracy to get rid of 'export'. :)

Not that the world isn't full of conspiracies, I mean, who hasn't participated
in tens if not hundreds of small conspiracies, and who trusts a lawyer
(regardless of country), a Norwegian sociologist, or an English politician?

But really, consider that what others consider important may not be the same as
what you consider important, and that it's practically impossible to mention
everything related to some issue X in every context where X is involved.

Also, consider that even if your ad hominem suggestion was true it would not be
a valid argument in favor of 'export', and also that there's no way to get
'export' reinstated in the language (not to mention getting it implemented).

Just relax: 'export' is gone, and perhaps we'll get something better later.


Cheers,

- Alf
 
J

Juha Nieminen

Alf P. Steinbach said:
He he, the great conspiracy to get rid of 'export'. :)

Yeah. I apologize if I'm sounding a bit frustrated.

I suppose I'll just have to learn to live with the fact, even though I don't like it...
Just relax: 'export' is gone, and perhaps we'll get something better later.

Seeing how long it has taken for C++0x to get ratified (it still hasn't), I don't have my hopes too high...
 
A

AnonMail2005

  Many people argue that there is *no* advantage in using export
templates other than the questionable advantage of being able to
separate the declaration from the implementation (which these people
seem to argue is only a purely cosmetic feature).

  However, I have *never* seen discussed the absolutely *major*
advantage of export templates: That they have their own compilation
unit, which means that they have access to their own file-local scope
(which in turn can be used to increase the modularity of the program).
This is something which is just not possible with regular templates.

  For that reason I have argued that template classes and functions
are actually *inferior* to regular classes and functions because the
former cannot have file-local scope while the latter can. Export
templates would solve this deficiency.

  I have been thinking about what would be the simplest example which
is implementable with export templates and which isn't with regular
templates (at least not without global namespace contamination). How
about this:

//---------------------------------------------------
// MyClass.hh
export template<typename T>
class MyClass
{
 public:
    MyClass();
    // other member functions here...};

//---------------------------------------------------

//---------------------------------------------------
// MyClass.cc
namespace
{
    unsigned constructorCallCounter = 0;

}

template<typename T>
MyClass<T>::MyClass()
{
    ++constructorCallCounter;}

//---------------------------------------------------

  You *could* achieve the same effect with regular templates, but
it would require adding a new name to global scope (accessible from
anywhere). This may not be a very viable solution if the amount of
stuff inside the nameless namespace above is large, nor is it very
good design.

  (And no, making 'constructorCallCounter' a static member of
MyClass is *not* the same thing because it would mean that every
distinct template instantiation would have its own separate
'constructorCallCounter', rather than it being shared among all
of them.)

  Can anyone come up with some objections to the example above?
(Note that the example is not intended to be an example of actual
usage, but instead the simplest possible example that demonstrates
the issue.)

This is what we do which I think gets at the benefits you mentioned w/
o using export:

1. Separate the code into a header (*.h) and an implementation file
(*.tcc). For instance, a template of some container would be
separated into a MyContainer.h and MyContainer.tcc.

2. Particular instances of MyContainer would be "implemented" using a
stub header and implementation file. The header would just be a
typedef (e.g. MyContainerInt.h) and would include only MyContainer.h.
The header is purely for ease of use and not required. The
implementation file (e.g MyContainerInt.cpp) would explicitly
instantiate the class and would include the MyContainer.tcc file.
Using explicit instatiation gives you a separate compilation unit.

3. Users of the MyContainerInt would only include MyContainerInt.h.

We used the above with success for our in house implementation of
smart pointers.

HTH
 
B

Brian

[ ... ]
  Some people argue that export templates have no advantages
whatsoever. This is a huge lie. I have *never* seen these people
talking about the issue of template classes and functions not
having local scope, while regular classes and functions, as well as
export templates do. It's like they are cherry-picking and choosing
only those alleged advantages which people think export templates
have but which are not very relevant.

While you're right that exported templates could sometimes provide
some benefit, the benefit really was fairly minimal and the cost
really was quite high. Worse, I believe their presence in the
standard tended to stall (if not outright prevent) work on anything
better. As such, removing export from the standard is almost
certainly for the best, because it'll allow something better to be
designed and put into use.

At the least it's quite depressing that export gets
dumped without anything related being adopted.
How long is it going to take for someone to build
a better approach? Wouldn't it have made more
sense to keep export until it's clear that there
is a better approach?


Brian Wood
http://webEbenezer.net
(651) 251-9384
 
B

Brian

That said, nobody prevents you from writing an implementation of
export. GCC is open source, just go for it. I wish you luck.

I think that's a poor suggestion. "When you're in a hole,
stop digging." "GCC development" is an oxymoron. Others
are working on C++ based alternatives, so there's no need
to mess around with GCC.


Brian Wood
http://webEbenezer.net
(651) 251-9384
 
J

James Kanze

[ ... ]
Some people argue that export templates have no advantages
whatsoever. This is a huge lie. I have *never* seen these
people talking about the issue of template classes and
functions not having local scope, while regular classes and
functions, as well as export templates do. It's like they
are cherry-picking and choosing only those alleged
advantages which people think export templates have but
which are not very relevant.
While you're right that exported templates could sometimes
provide some benefit, the benefit really was fairly minimal
and the cost really was quite high.

Since when is improved encapsulation a "minimal" benefit. And
from a user point of view: I get the benefit, but the cost is
paid by the compiler vendor. (I know that that's somewhat
simplified, but you get the idea.)
Worse, I believe their presence in the standard tended to
stall (if not outright prevent) work on anything better.

That is a potential problem. I rather opposed namespaces in the
original standard for more or less the same reason. But as the
situation now stands, we're not going to get anything better
soon.
As such, removing export from the standard is almost certainly
for the best, because it'll allow something better to be
designed and put into use.

Something better has already been proposed, but not adopted, for
lack of time. Perhaps if as much effort had been put into it as
was put into getting rid of export. (Had the proposal been to
replace export with something better, I'd not be opposed.)
 
J

James Kanze

Of course, the future is always uncertain. Nonetheless, I'd
say the chances of C++ getting a useful and usable module
system increased substantially when "export" was removed.

The chances of getting a useful and usable module system would
be higher if the effort spent in getting rid of export had been
spent on improving the proposal for module.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,021
Latest member
AkilahJaim

Latest Threads

Top