Topic: Template writing strategies
Author: Kaba <none@here.com>
Date: Mon, 13 Feb 2006 13:29:29 CST Raw View
> You may be interested in paper N1496
> (http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1496.html) and a
> long, sometimes confusing, discussion I had with its author. Google for
> 'Virtually_destructible' in comp.lang.c++.moderated and comp.std.c++.
Wil,
thanks for the tip. I read through the paper and the conversation. While
interesting, the subject of this thread (controlling template
instantiation) is separate from that topic (portable dynamic linking).
Btw: the bibliography at end of the paper reads
* Austern, Matthew, "Toward Standardization of Dynamic Libraries", N1400
=02-0058, 2002.
I wasn't able to find this through google. Is there a place, where I can
find all proposals?
--
Kalle Rutanen
http://kaba.hilvi.org
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: bouncer@dev.null (Wil Evers)
Date: Tue, 14 Feb 2006 04:06:37 GMT Raw View
Kaba wrote:
>> You may be interested in paper N1496
>> (http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1496.html) and
>> a
>> long, sometimes confusing, discussion I had with its author. Google for
>> 'Virtually_destructible' in comp.lang.c++.moderated and comp.std.c++.
>
> thanks for the tip. I read through the paper and the conversation. While
> interesting, the subject of this thread (controlling template
> instantiation) is separate from that topic (portable dynamic linking).
Well, yes and no. One of the reasons for the need to control template
instantiation is to avoid duplicate copies when the same instantiation
appears in more than one of the modules (DLLs) that eventually end up in a
single program's address space. I tried to point out that, at least by
default, some dynamic linkers will automatically merge such duplicate
instantiations, while others will not.
> Btw: the bibliography at end of the paper reads
> * Austern, Matthew, "Toward Standardization of Dynamic Libraries", N1400
> =02-0058, 2002.
>
> I wasn't able to find this through google. Is there a place, where I can
> find all proposals?
Most are available through
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/
N1400 is in the listing for the year 2002.
- Wil
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: eldiener_no_spam_here@earthlink.net (Edward Diener No Spam)
Date: Thu, 9 Feb 2006 15:42:21 GMT Raw View
Kaba wrote:
> Hello Edward
>
> I'll take a correction before replying to you. The "separation model"
> name was not a good name choice, because it is already in use describing
> the use of export. I'll call it my separation model then (for these
> postings)..
>
>> Since you must include both the template declaration ( .h files in your
>> example ) and template definition anyway, I do not understand what your
>> separation model is supposed to accomplish. Ideally you have a good idea
>> but, barring "export" which is a better one, there is currently no way
>> to simply include the template declaration and be able to use templates,
>> similar to the way that one can simple include declarations in the
>> non-template case and use classes.
>
> There is a way to use a template with only a template declaration and
> without export by using explicit instantiation. Here:
>
> application.cpp
> ---------------
>
> #include "mytemplate.hpp"
>
> template class A<int>;
>
> int main()
> {
> return 0;
> }
>
> application2.cpp
> ----------------
>
> #include "mytemplate.h"
>
> void f()
> {
> A<int> a;
> a.f();
> }
>
> In short, this is the thing we accomplish.
Yes, I understand this. Nevertheless you are still explicitly
instantiating whatever you need to make this work. If the programmer
wants to instantiate a template with types which are not already in an
explicit insstantiation, he must once again access the template
definition by including mytemplate.hpp.
>
> Now, lets consider traditional C++ programming, where you have a bunch
> of translation units which you compile and link together. Why would you
> use such a style? It is clearly inconvenient, because you would have to
> manually instantiate every function you use somewhere. There is a speed
> up in compilation times, because:
> - the code is generated only once for each function.
> - the template code is not included where it is not needed.
> In summary, for traditional C++ programming, the advantage of the
> separation is only cosmetic.
>
> Now, lets consider programming with dynamic link libraries. Lets call a
> dynamic link library and an executable with a common name module. If you
> instantiate a template in module A, and instantiate the same template in
> module B, then there exists two copies of the same code. If this isn't
> serious enough
It is not serious at all.
>, there also exists two separate copies of the class
> variables.
This is a potential problem, but it is no different than having a type
in a DLL and the same type in an EXE, where the type has class variables.
> Now, we usually don't like the idea of code replication
> (except where we deliberately inline), so we would like to maintain the
> code in module A, and let module B use the code from module A. Thus,
> there is only one instance of the code and one instance of a class
> variable.
Ideally very nice.
>
> Fine, that seems like a solution. But how do we do this in practice?
> Because of implicit instantiation, if the template code is present, the
> functions will be generated. I am aware of two solutions, from which
> the other is what I am proposing:
"the other" what ?
>
> 1) There has been one proposal, the N1448. It suggests to add an
> extension to the language, the export to the explicit instantiation. Its
> meaning is to say "do not generate an instantiation of this type in any
> circumstances, although you have the template code present".
>
> 2) Do not give the template code at all, just the class definition (or
> function declaration).
>
> Now imagine you are working on a factory, which produces soft rabbits.
> It has the following work-flow:
>
> 1) The soft rabbits are produced
> 2) Rabbits are added some clothing to make them more interesting.
> 3) The clothing is removed and the original soft rabbits sent to
> customers.
>
> Your mission is to cut down the costs of producing the soft rabbits. Can
> you spot any flaws and improve the workflow? :)
This is a very bad argument. One cares about a good model for template
declarations vis-a-vis template definitions. Why bring in this metaphor.
It is irrelevant and just obfuscating whatever your idea is.
>
> To further provocate, I claim that export is not the right analog for
> interface/implementation separation between templates and normal
> classes/functions. I say that my separation model is the one.
>
> And why? For this I'd like to note that export does actually two
> separations:
> 1) Separation of interface and implementation
> 2) Separation of instantion file from the template file (and this is
> where we get into the trouble).
>
> The separation in 2 is an unlogical one: there always exists the
> dependence between the template code and the instantiating code. I don't
> think one should pretend that there is not.
I lost you and do not know for what you are arguing. But I will give you
what I consider the theoretical right model, and it is not your own of
having to use explicit instantiations of templates to generate types and
then hope the programmer does not need to use the template to generate
types which have not been anticipated ( the last being the great flaw of
your model ). My theoretical model does not exist today in C++ but if
you use your imagination you can understand it. Here goes:
For types not generated for templates, C++ using a header file to
declare the type and a source files to compile the type's definition to
some intermediary form, let's say an object file ( library, shared
library ). The latter gets distributed with code usually in the form of
a library, which the end-user generally does not and need not be able to
understand, but which that end-user can link with to create a final
module. The declaration is distributed in its form as a header file, and
the compiler uses this declaration in the header in order to make sure
that the end-user is using the type directly when compiling his code. In
essence the type declaration is used by the compiler, and the type
definition/code is used by the linker. I realize that the C++ standard
really says nothing about the latter, and that obviously the type
definition can be distributed as a source file and compiled directly
into the module, but let's for the sake of example say that the type
declaration/compiler and type definition/linker model is a valid one for
those who want to create types ( classes ) but who do not wanrt to
distribute their source code.
What I want to see with templates is a similar separation. The template
definition, like the type definition in our previous example, gets
"compiled" down to some intermediate form which the end-user neither
knows about ot cares about, and gets distributed in that form. The
template declaration gets distributed as a header file with, let's say,
a nice little keyword, let's call it "EdsExport" <g>, which tells the
compiler to look at the equivalent intermediate form template definition
for checking during phase 1 of two-phase lookup, and to generate the
correct code for the linker during phase 2 of two-phase lookup. The
end-user only has the template declaration in a header file and this
intermediate form template definition file, which BTW like an object
library may contain more than one template definition. The end-user does
not care about the template definition and never looks at it, but only
sees the template declaration. Essentially this mimics the way source
code and header files work with C++ types while preserving the
intellectual property of the template definition source code if the
original creator of that code so wishes.
Your separation model, with template instantiations, is a clever one but
does not solve the problem which I want solved, and has the flaw that
it only works as a separation model when one completely anticipates what
types the user wants to use in the instantiation of any given template.
My solution does not exist but 'export' is a step in that direction. It
is not the full step I want but a compiler implementor could make it so,
and obviously the C++ standard committee could make it more so with
perhaps a more visionary approach than they are wont to take.
IMO, your separation model is a good one, but it is not a complete
solution, and the only complete solution is to extend the "export" model
to produce a true separation of template definition from template
declaration in such a way that the actual template definition does not
need to be present in source form and referenced via a header file, for
an end-user to instantiate a template with any valid type from a
template declaration header file.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: none@here.com (Kaba)
Date: Fri, 10 Feb 2006 04:50:13 GMT Raw View
> Yes, I understand this. Nevertheless you are still explicitly
> instantiating whatever you need to make this work. If the programmer
> wants to instantiate a template with types which are not already in an
> explicit insstantiation, he must once again access the template
> definition by including mytemplate.hpp.
Yes, the point is that templates are only generators. If you were to
build plug-ins, the set of needed instantiations would be finite. You
are requiring an infinite set of possible instantiations.
> > Now, lets consider programming with dynamic link libraries. Lets call a
> > dynamic link library and an executable with a common name module. If you
> > instantiate a template in module A, and instantiate the same template in
> > module B, then there exists two copies of the same code. If this isn't
> > serious enough
>
> It is not serious at all.
It does not affect execution of the program, but it does form a
maintenance problem. One of the main points of modules is to make it
possible to compile them, to some extent, without regard to other
modules.
> >, there also exists two separate copies of the class
> > variables.
>
> This is a potential problem, but it is no different than having a type
> in a DLL and the same type in an EXE, where the type has class variables.
I don't understand what you are saying... The separation of global
variables is really serious, because it affects the execution and makes
the program frequently behave incorrectly.
> "the other" what ?
The option 2, "do not give the template code at all"
> > 1) There has been one proposal, the N1448. It suggests to add an
> > extension to the language, the export to the explicit instantiation. Its
> > meaning is to say "do not generate an instantiation of this type in any
> > circumstances, although you have the template code present".
I made a typo here, replace export with extern..
> > 2) Do not give the template code at all, just the class definition (or
> > function declaration).
> >
> > Now imagine you are working on a factory, which produces soft rabbits.
> > It has the following work-flow:
> >
> > 1) The soft rabbits are produced
> > 2) Rabbits are added some clothing to make them more interesting.
> > 3) The clothing is removed and the original soft rabbits sent to
> > customers.
> >
> > Your mission is to cut down the costs of producing the soft rabbits. Can
> > you spot any flaws and improve the workflow? :)
>
> This is a very bad argument. One cares about a good model for template
> declarations vis-a-vis template definitions. Why bring in this metaphor.
> It is irrelevant and just obfuscating whatever your idea is.
I am sorry, I thought the analog was very clear. The soft rabbits are
the class definitions and the clothing are the class member function
definitions (implementation). My point was to cast the problem in other
domain to make it clear that the use of "extern" on explicit
instantiations is not natural.
I did forgot one detail: that the rabbits with clothes were delivered
internally to the workers, and thats why the clothing (template code)
was needed in the first place. Then the answer to the problem was to
divide the work-flow into two: the others add clothes to rabbits (class
definitions and member function definitions) and send them to workers
(main program) while the others just package the plain soft rabbits
(class definitions) and send them to customers (plug-ins).
> Your separation model, with template instantiations, is a clever one but
> does not solve the problem which I want solved, and has the flaw that
> it only works as a separation model when one completely anticipates what
> types the user wants to use in the instantiation of any given template.
> My solution does not exist but 'export' is a step in that direction. It
> is not the full step I want but a compiler implementor could make it so,
> and obviously the C++ standard committee could make it more so with
> perhaps a more visionary approach than they are wont to take.
> IMO, your separation model is a good one, but it is not a complete
> solution, and the only complete solution is to extend the "export" model
> to produce a true separation of template definition from template
> declaration in such a way that the actual template definition does not
> need to be present in source form and referenced via a header file, for
> an end-user to instantiate a template with any valid type from a
> template declaration header file.
First, the conversion of the template code to the intermediate form is
not important. In any case, we _need_ the template source code, in some
form or another, to generate a specific instantiation drawn from a
(practically) infinite set.
An implication of this is, that if we want to preserve this property
across modules, then we must copy the code. In small scale this could be
ok, but not in the large scale and absolutely not with small plug-ins.
Consider plug-ins: if the system were implemented without templates,
that is, with normal classes (functions), then there would be a finite
set of them, and all would be fine. What is it that makes you think that
templates should take this property away? They shouldn't: they should be
tought as generators for a finite set of classes: infinity is clearly
impossible.
Here is what I am arguing for:
* the infinite set of instantiations is not possible without the
template code, in some form or another.
* therefore, if we want to avoid code replication and exposition, we
need to constrain the set to a finite one
* using my separation model, the user can choose between instantiation
and replication.
* the export model does not have any useful additional properties over
this model.
* the "extern" extension proposal is not natural and should not be
adopted into the standard. There is a more natural option, which is what
I am arguing for.
--
Kalle Rutanen
http://kaba.hilvi.org
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: benhongh@yahoo.com.au (benben)
Date: Fri, 10 Feb 2006 19:31:46 GMT Raw View
Kaba wrote:
> Hello
>
> I posted a few weeks ago, with the title "Abstraction layer
> correctness". The given link was this:
>
> http://kaba.hilvi.org/project/abstraction/index.htm
>
> My aim was to raise conversation over the proposal, but there were
> relatively little replies. Discussion with Alberto Ganesh Barbati was
> greatly appreciated, it could have continued though..
>
> I am a little confused what this kind of "silence" means.. I hope
> someone has given it a thought. I am happy that 40 visitors had at least
> a quick glance at the page:) Anyway.. I'd still appreciate conversation
> and most notably, dialogs not monologs.
>
> If the text seems too lengthy, I'll give here the main points,
> deliberately a little provocative, if I may:)
>
> * There are many ways to write templates
> * Excluding export, one way is more able than the others (call it the
> separation model)
> * Generally, templates should always be written using the separation
> model.
> * Without the separation model, there will be notable compile-time
> slowdowns.
> * Without the separation model, we will need the "extern"-extension to
> templates work with dlls.
> * STL does not use the separation model
>
> Now, what is the separation model?
>
> Simply by an example:
>
> mytemplate.h
> ------------
>
> template <typename T>
> class A
> {
> public:
> void f();
> private:
> int data_;
> };
>
> mytemplate.hpp
> --------------
>
> #include "mytemplate.h"
>
> template <typename T>
> void A::f()
> {
> data_ = 4;
> }
>
> mytemplate2.h
> -------------
>
> #include "mytemplate.h"
>
> template <typename T>
> class B
> {
> public:
> void g();
> };
>
> mytemplate2.hpp
> ---------------
>
> #include "mytemplate2.h"
>
> template <typename T>
> void B<int>::g()
> {
> }
>
> application.cpp
> ---------------
>
> #include "mytemplate2.hpp"
> #include "mytemplate.hpp"
>
> int main()
> {
> A<int> a;
> a.f();
> B<int> b;
> b.f();
> }
>
> Observe the following important points:
> * .h files only give class definitions and function declarations
> * .hpp files give function definitions
> * Note analogue to .h and .cpp
> * We create a separation between implementation and interface.
>
> Now _this_ should be provocative enough to raise conversation:)
>
What I'd do is:
// matrix_decl.hpp ///////////////////////
template <typename T>
class matrix
{
public:
T& at(unsigned int x, unsigned int y);
// other declarations
};
// matrix.hpp ////////////////////////////
#include "matrix_decl.hpp"
template <typename T>
T& matrix<T>::at(unsigned int x, unsigned int y)
{
// yada yada yada
}
// ...
// app.cpp ///////////////////////////////
#include "matrix.hpp"
int main()
{
matrix<double> m(4, 5);
// ...
}
Regards,
Ben
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: none@here.com (Kaba)
Date: Sat, 11 Feb 2006 01:53:48 GMT Raw View
I wrote the whole article on the subject from the start, including the
suggested problems discussed here. I think it should be very clear now
on why I propose what I do. No fancy metaphors. I hope you are not
getting tired yet... Thank you for the interest this far.
A direct link to a pdf:
http://kaba.hilvi.org/project/abstraction/nsm.pdf
Or use a link from (remember to refresh):
http://kaba.hilvi.org/project/abstraction/index.htm
--
Kalle Rutanen
http://kaba.hilvi.org
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: none@here.com (Kaba)
Date: Sat, 11 Feb 2006 07:22:44 GMT Raw View
> What I'd do is:
>
> // matrix_decl.hpp ///////////////////////
>
> template <typename T>
> class matrix
> {
> public:
> T& at(unsigned int x, unsigned int y);
> // other declarations
> };
>
>
> // matrix.hpp ////////////////////////////
> #include "matrix_decl.hpp"
>
> template <typename T>
> T& matrix<T>::at(unsigned int x, unsigned int y)
> {
> // yada yada yada
> }
> // ...
>
> // app.cpp ///////////////////////////////
> #include "matrix.hpp"
>
> int main()
> {
> matrix<double> m(4, 5);
> // ...
> }
So would I and that is exactly the thing I am proposing that should be
added to STL..
--
Kalle Rutanen
http://kaba.hilvi.org
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: eldiener_no_spam_here@earthlink.net (Edward Diener No Spam)
Date: Sat, 11 Feb 2006 07:23:43 GMT Raw View
Kaba wrote:
>> Yes, I understand this. Nevertheless you are still explicitly
>> instantiating whatever you need to make this work. If the programmer
>> wants to instantiate a template with types which are not already in an
>> explicit insstantiation, he must once again access the template
>> definition by including mytemplate.hpp.
>
> Yes, the point is that templates are only generators. If you were to
> build plug-ins, the set of needed instantiations would be finite. You
> are requiring an infinite set of possible instantiations.
Your solution is one for plug-ins/DLLs. It does not solve the ultimate
problem of completely separating the template declaration from template
definition and allowing as many types created from the template as the
template will legally allow. A template often allows very many less than
an infinite set of possibile instantiations, as I am sure you know.
>
>>> Now, lets consider programming with dynamic link libraries. Lets call a
>>> dynamic link library and an executable with a common name module. If you
>>> instantiate a template in module A, and instantiate the same template in
>>> module B, then there exists two copies of the same code. If this isn't
>>> serious enough
>> It is not serious at all.
>
> It does not affect execution of the program, but it does form a
> maintenance problem. One of the main points of modules is to make it
> possible to compile them, to some extent, without regard to other
> modules.
>
>>> , there also exists two separate copies of the class
>>> variables.
>> This is a potential problem, but it is no different than having a type
>> in a DLL and the same type in an EXE, where the type has class variables.
>
> I don't understand what you are saying... The separation of global
> variables is really serious, because it affects the execution and makes
> the program frequently behave incorrectly.
>
>> "the other" what ?
>
> The option 2, "do not give the template code at all"
>
>>> 1) There has been one proposal, the N1448. It suggests to add an
>>> extension to the language, the export to the explicit instantiation. Its
>>> meaning is to say "do not generate an instantiation of this type in any
>>> circumstances, although you have the template code present".
>
> I made a typo here, replace export with extern..
>
>>> 2) Do not give the template code at all, just the class definition (or
>>> function declaration).
>>>
>>> Now imagine you are working on a factory, which produces soft rabbits.
>>> It has the following work-flow:
>>>
>>> 1) The soft rabbits are produced
>>> 2) Rabbits are added some clothing to make them more interesting.
>>> 3) The clothing is removed and the original soft rabbits sent to
>>> customers.
>>>
>>> Your mission is to cut down the costs of producing the soft rabbits. Can
>>> you spot any flaws and improve the workflow? :)
>> This is a very bad argument. One cares about a good model for template
>> declarations vis-a-vis template definitions. Why bring in this metaphor.
>> It is irrelevant and just obfuscating whatever your idea is.
>
> I am sorry, I thought the analog was very clear. The soft rabbits are
> the class definitions and the clothing are the class member function
> definitions (implementation). My point was to cast the problem in other
> domain to make it clear that the use of "extern" on explicit
> instantiations is not natural.
>
> I did forgot one detail: that the rabbits with clothes were delivered
> internally to the workers, and thats why the clothing (template code)
> was needed in the first place. Then the answer to the problem was to
> divide the work-flow into two: the others add clothes to rabbits (class
> definitions and member function definitions) and send them to workers
> (main program) while the others just package the plain soft rabbits
> (class definitions) and send them to customers (plug-ins).
>
>> Your separation model, with template instantiations, is a clever one but
>> does not solve the problem which I want solved, and has the flaw that
>> it only works as a separation model when one completely anticipates what
>> types the user wants to use in the instantiation of any given template.
>
>> My solution does not exist but 'export' is a step in that direction. It
>> is not the full step I want but a compiler implementor could make it so,
>> and obviously the C++ standard committee could make it more so with
>> perhaps a more visionary approach than they are wont to take.
>
>> IMO, your separation model is a good one, but it is not a complete
>> solution, and the only complete solution is to extend the "export" model
>> to produce a true separation of template definition from template
>> declaration in such a way that the actual template definition does not
>> need to be present in source form and referenced via a header file, for
>> an end-user to instantiate a template with any valid type from a
>> template declaration header file.
>
> First, the conversion of the template code to the intermediate form is
> not important. In any case, we _need_ the template source code, in some
> form or another, to generate a specific instantiation drawn from a
> (practically) infinite set.
What I am saying is that the template source can be obfuscated in an
intermediate form, just like non-template source is obfuscated in the
form of object files/libraries. But you are right that this is really
not the point. What I am saying is that, under my theoretical solution,
the programmer should be able to include just the template declaration
and the template definition will automatically be found, in whatever
form it is distributed by the template creator.
>
> An implication of this is, that if we want to preserve this property
> across modules, then we must copy the code. In small scale this could be
> ok, but not in the large scale and absolutely not with small plug-ins.
>
> Consider plug-ins: if the system were implemented without templates,
> that is, with normal classes (functions), then there would be a finite
> set of them, and all would be fine. What is it that makes you think that
> templates should take this property away? They shouldn't: they should be
> tought as generators for a finite set of classes: infinity is clearly
> impossible.
>
> Here is what I am arguing for:
> * the infinite set of instantiations is not possible without the
> template code, in some form or another.
> * therefore, if we want to avoid code replication and exposition, we
> need to constrain the set to a finite one
> * using my separation model, the user can choose between instantiation
> and replication.
> * the export model does not have any useful additional properties over
> this model.
Yes, it does. It allows for the programmer to instantiate whatever types
he wants from a template, which the template will allow, without the
constraint of the template developer pre-deciding which types are allowed.
Your solution is a good one for splitting template usage across modules.
I do not deny that. All that I am saying is that it is not the ideal
solution in my mind to the separation of template declarations from
template definitions, and I am not speaking about just the splitting of
template usage across modules.
There is nothing in "export", even as it is now, that precludes you from
doing what you want to do, which is essentially pre-instantiation of a
set of types from a template and the distribution of a template
declaration only which will work if only used with those types. I am
still, however going to say to you that this is not a complete situation
to the problem of template separation of declaration and definition as I
see it.
> * the "extern" extension proposal is not natural and should not be
> adopted into the standard. There is a more natural option, which is what
> I am arguing for.
I do not know about the "extern" proposal, and am not arguing for or
against it. I can look at it, but since my vision for separation of
template declaration from definition is more radical than what already
exists, I am sure I would view it, like your own separation model, as
merely another step toward the ultimately correct solution to the
problem in my own mind.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: bouncer@dev.null (Wil Evers)
Date: Mon, 13 Feb 2006 00:12:53 GMT Raw View
Kaba wrote:
> I posted a few weeks ago, with the title "Abstraction layer
> correctness". The given link was this:
>
> http://kaba.hilvi.org/project/abstraction/index.htm
>
> My aim was to raise conversation over the proposal, but there were
> relatively little replies. Discussion with Alberto Ganesh Barbati was
> greatly appreciated, it could have continued though..
>
> I am a little confused what this kind of "silence" means.. I hope
> someone has given it a thought. I am happy that 40 visitors had at least
> a quick glance at the page:) Anyway.. I'd still appreciate conversation
> and most notably, dialogs not monologs.
>
> If the text seems too lengthy, I'll give here the main points,
> deliberately a little provocative, if I may:)
>
> * There are many ways to write templates
> * Excluding export, one way is more able than the others (call it the
> separation model)
> * Generally, templates should always be written using the separation
> model.
> * Without the separation model, there will be notable compile-time
> slowdowns.
> * Without the separation model, we will need the "extern"-extension to
> templates work with dlls.
> * STL does not use the separation model
You may be interested in paper N1496
(http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1496.html) and a
long, sometimes confusing, discussion I had with its author. Google for
'Virtually_destructible' in comp.lang.c++.moderated and comp.std.c++.
- Wil
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: none@here.com (Kaba)
Date: Mon, 13 Feb 2006 16:12:56 GMT Raw View
(My reply seems to have disappeared somewhere on its way, so I post this
again)
> Your solution is one for plug-ins/DLLs. It does not solve the ultimate
> problem of completely separating the template declaration from template
> definition and allowing as many types created from the template as the
> template will legally allow. A template often allows very many less than
> an infinite set of possibile instantiations, as I am sure you know.
Yes, the problem itself exists only between DLLs. With a one-module
program the programmer can use whatever style he/she wants to and still
get equivalent results. This changes with multiple modules.
Of course, there are a finite amount of possible template
instantiations, but practically there is such an enormous amount of them
that infinity is a short and descriptive word to describe the situation.
> What I am saying is that the template source can be obfuscated in an
> intermediate form, just like non-template source is obfuscated in the
> form of object files/libraries. But you are right that this is really
> not the point. What I am saying is that, under my theoretical solution,
> the programmer should be able to include just the template declaration
> and the template definition will automatically be found, in whatever
> form it is distributed by the template creator.
I understand the obfuscation as a possible solution to the template code
exposure problem. Your proposal is similar to how export works. I'd like
to note there is nothing that export can do that an inclusion model
can't. Here inclusion model = any technique that directly includes
implementation in the instantiating file.
Export is a solution to the problem "do I really have to write that one
line to include the template implementation everywhere I use the
template?". It is a nice idea, but given the advantages (no need to
write the inclusion line) and disadvantages it creates for compilers
(huge!), I think export should not exist.
http://www.gotw.ca/publications/mill23.htm
That article propably explains this better. In short, at first it seems
like a good idea, but once you start thinking about it, it really gets
into a nightmare and you start wondering whether this really is worth of
avoiding the writing of a one line per source file "#include
<implementation>".
Note the dependence between templates and the instantiating code is
bidirectional. Instantiating code uses the template code and the
template code is dependent on the types it is instantiated with.
> > * the export model does not have any useful additional properties over
> > this model.
>
> Yes, it does. It allows for the programmer to instantiate whatever types
> he wants from a template, which the template will allow, without the
> constraint of the template developer pre-deciding which types are allowed.
I disagree. Assuming one-module program, this can be done with inclusion
model also. Assuming multiple-module program, export results in code
replication just as the inclusion model. They are equivalent, it's just
a matter whether you write the inclusion line or not.
> Your solution is a good one for splitting template usage across modules.
> I do not deny that. All that I am saying is that it is not the ideal
> solution in my mind to the separation of template declarations from
> template definitions, and I am not speaking about just the splitting of
> template usage across modules.
I can understand this. But as we have learnt from export, the separation
is an illusion: the dependence still exists, just hidden from human
eyes. The disadvantages are far greater than the advantages.
> There is nothing in "export", even as it is now, that precludes you from
> doing what you want to do, which is essentially pre-instantiation of a
> set of types from a template and the distribution of a template
> declaration only which will work if only used with those types. I am
True.
> still, however going to say to you that this is not a complete situation
> to the problem of template separation of declaration and definition as I
> see it.
Talking about just physical separation, I see my solution as natural. It
is only natural that the template code is included when it is used,
because the dependence between instantiating types and the template is
always there.
> I do not know about the "extern" proposal, and am not arguing for or
> against it. I can look at it, but since my vision for separation of
> template declaration from definition is more radical than what already
> exists, I am sure I would view it, like your own separation model, as
> merely another step toward the ultimately correct solution to the
> problem in my own mind.
Note I am arguing more for the solution to the implicit instantion
problem with dlls rather than the physical separation problem. Whether
the template should be included directly (inclusion) or indirectly
(export) is a separate question.
Regarding your model, of which workings I did not grasp in detail, a few
questions:
* Could you give an example of its (imaginary) use?
* Is it able to solve the code replication problem between modules?
--
Kalle Rutanen
http://kaba.hilvi.org
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: none@here.com (Kaba)
Date: Mon, 13 Feb 2006 18:59:19 GMT Raw View
> Your solution is one for plug-ins/DLLs. It does not solve the ultimate
> problem of completely separating the template declaration from template
> definition and allowing as many types created from the template as the
> template will legally allow. A template often allows very many less than
> an infinite set of possibile instantiations, as I am sure you know.
Yes, the problem itself exists only between DLLs. With a one-module
program the programmer can use whatever style he/she wants to and still
get equivalent results. This changes with multiple modules.
Of course, there are a finite amount of possible template
instantiations, but practically there is such an enormous amount of them
that infinity is a short and descriptive word to describe the situation.
> What I am saying is that the template source can be obfuscated in an
> intermediate form, just like non-template source is obfuscated in the
> form of object files/libraries. But you are right that this is really
> not the point. What I am saying is that, under my theoretical solution,
> the programmer should be able to include just the template declaration
> and the template definition will automatically be found, in whatever
> form it is distributed by the template creator.
I understand the obfuscation as a possible solution to the template code
exposure problem. Your proposal is similar to how export works. I'd like
to note there is nothing that export can do that an inclusion model
can't. Here inclusion model = any technique that directly includes
implementation in the instantiating file.
Export is a solution to the problem "do I really have to write that one
line to include the template implementation everywhere I use the
template?". It is a nice idea, but given the advantages (no need to
write the inclusion line) and disadvantages it creates for compilers
(huge!), I think export should not exist.
http://www.gotw.ca/publications/mill23.htm
That article propably explains this better. In short, at first it seems
like a good idea, but once you start thinking about it, it really gets
into a nightmare and you start wondering whether this really is worth of
avoiding the writing of a one line per source file "#include
<implementation>".
Note the dependence between templates and the instantiating code is
bidirectional. Instantiating code uses the template code and the
template code is dependent on the types it is instantiated with.
> > * the export model does not have any useful additional properties over
> > this model.
>
> Yes, it does. It allows for the programmer to instantiate whatever types
> he wants from a template, which the template will allow, without the
> constraint of the template developer pre-deciding which types are allowed.
I disagree. Assuming one-module program, this can be done with inclusion
model also. Assuming multiple-module program, export results in code
replication just as the inclusion model. They are equivalent, it's just
a matter whether you write the inclusion line or not.
> Your solution is a good one for splitting template usage across modules.
> I do not deny that. All that I am saying is that it is not the ideal
> solution in my mind to the separation of template declarations from
> template definitions, and I am not speaking about just the splitting of
> template usage across modules.
I can understand this. But as we have learnt from export, the separation
is an illusion: the dependence still exists, just hidden from human
eyes. The disadvantages are far greater than the advantages.
> There is nothing in "export", even as it is now, that precludes you from
> doing what you want to do, which is essentially pre-instantiation of a
> set of types from a template and the distribution of a template
> declaration only which will work if only used with those types. I am
True.
> still, however going to say to you that this is not a complete situation
> to the problem of template separation of declaration and definition as I
> see it.
Talking about just physical separation, I see my solution as natural. It
is only natural that the template code is included when it is used,
because the dependence between instantiating types and the template is
always there.
> I do not know about the "extern" proposal, and am not arguing for or
> against it. I can look at it, but since my vision for separation of
> template declaration from definition is more radical than what already
> exists, I am sure I would view it, like your own separation model, as
> merely another step toward the ultimately correct solution to the
> problem in my own mind.
Note I am arguing more for the solution to the implicit instantion
problem with dlls rather than the physical separation problem. Whether
the template should be included directly (inclusion) or indirectly
(export) is a separate question.
Regarding your model, of which workings I did not grasp in detail, a few
questions:
* Could you give an example of its (imaginary) use?
* Is it able to solve the code replication problem between modules?
--
Kalle Rutanen
http://kaba.hilvi.org
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: none@here.com (Kaba)
Date: Tue, 7 Feb 2006 21:39:25 GMT Raw View
Hello
I posted a few weeks ago, with the title "Abstraction layer
correctness". The given link was this:
http://kaba.hilvi.org/project/abstraction/index.htm
My aim was to raise conversation over the proposal, but there were
relatively little replies. Discussion with Alberto Ganesh Barbati was
greatly appreciated, it could have continued though..
I am a little confused what this kind of "silence" means.. I hope
someone has given it a thought. I am happy that 40 visitors had at least
a quick glance at the page:) Anyway.. I'd still appreciate conversation
and most notably, dialogs not monologs.
If the text seems too lengthy, I'll give here the main points,
deliberately a little provocative, if I may:)
* There are many ways to write templates
* Excluding export, one way is more able than the others (call it the
separation model)
* Generally, templates should always be written using the separation
model.
* Without the separation model, there will be notable compile-time
slowdowns.
* Without the separation model, we will need the "extern"-extension to
templates work with dlls.
* STL does not use the separation model
Now, what is the separation model?
Simply by an example:
mytemplate.h
------------
template <typename T>
class A
{
public:
void f();
private:
int data_;
};
mytemplate.hpp
--------------
#include "mytemplate.h"
template <typename T>
void A::f()
{
data_ = 4;
}
mytemplate2.h
-------------
#include "mytemplate.h"
template <typename T>
class B
{
public:
void g();
};
mytemplate2.hpp
---------------
#include "mytemplate2.h"
template <typename T>
void B<int>::g()
{
}
application.cpp
---------------
#include "mytemplate2.hpp"
#include "mytemplate.hpp"
int main()
{
A<int> a;
a.f();
B<int> b;
b.f();
}
Observe the following important points:
* .h files only give class definitions and function declarations
* .hpp files give function definitions
* Note analogue to .h and .cpp
* We create a separation between implementation and interface.
Now _this_ should be provocative enough to raise conversation:)
--
Kalle Rutanen
http://kaba.hilvi.org
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: Edward Diener No Spam <eldiener_no_spam_here@earthlink.net>
Date: Wed, 8 Feb 2006 08:07:22 CST Raw View
Kaba wrote:
> Hello
>
> I posted a few weeks ago, with the title "Abstraction layer
> correctness". The given link was this:
>
> http://kaba.hilvi.org/project/abstraction/index.htm
>
> My aim was to raise conversation over the proposal, but there were
> relatively little replies. Discussion with Alberto Ganesh Barbati was
> greatly appreciated, it could have continued though..
>
> I am a little confused what this kind of "silence" means.. I hope
> someone has given it a thought. I am happy that 40 visitors had at least
> a quick glance at the page:) Anyway.. I'd still appreciate conversation
> and most notably, dialogs not monologs.
>
> If the text seems too lengthy, I'll give here the main points,
> deliberately a little provocative, if I may:)
>
> * There are many ways to write templates
> * Excluding export, one way is more able than the others (call it the
> separation model)
> * Generally, templates should always be written using the separation
> model.
> * Without the separation model, there will be notable compile-time
> slowdowns.
> * Without the separation model, we will need the "extern"-extension to
> templates work with dlls.
> * STL does not use the separation model
>
> Now, what is the separation model?
>
> Simply by an example:
>
> mytemplate.h
> ------------
>
> template <typename T>
> class A
> {
> public:
> void f();
> private:
> int data_;
> };
>
> mytemplate.hpp
> --------------
>
> #include "mytemplate.h"
>
> template <typename T>
> void A::f()
> {
> data_ = 4;
> }
>
> mytemplate2.h
> -------------
>
> #include "mytemplate.h"
>
> template <typename T>
> class B
> {
> public:
> void g();
> };
>
> mytemplate2.hpp
> ---------------
>
> #include "mytemplate2.h"
>
> template <typename T>
> void B<int>::g()
> {
> }
>
> application.cpp
> ---------------
>
> #include "mytemplate2.hpp"
> #include "mytemplate.hpp"
>
> int main()
> {
> A<int> a;
> a.f();
> B<int> b;
> b.f();
> }
Since you must include both the template declaration ( .h files in your
example ) and template definition anyway, I do not understand what your
separation model is supposed to accomplish. Ideally you have a good idea
but, barring "export" which is a better one, there is currently no way
to simply include the template declaration and be able to use templates,
similar to the way that one can simple include declarations in the
non-template case and use classes.
>
> Observe the following important points:
> * .h files only give class definitions and function declarations
> * .hpp files give function definitions
> * Note analogue to .h and .cpp
> * We create a separation between implementation and interface.
All understood, but see above.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: none@here.com (Kaba)
Date: Wed, 8 Feb 2006 17:14:51 GMT Raw View
Hello Edward
I'll take a correction before replying to you. The "separation model"
name was not a good name choice, because it is already in use describing
the use of export. I'll call it my separation model then (for these
postings)..
> Since you must include both the template declaration ( .h files in your
> example ) and template definition anyway, I do not understand what your
> separation model is supposed to accomplish. Ideally you have a good idea
> but, barring "export" which is a better one, there is currently no way
> to simply include the template declaration and be able to use templates,
> similar to the way that one can simple include declarations in the
> non-template case and use classes.
There is a way to use a template with only a template declaration and
without export by using explicit instantiation. Here:
application.cpp
---------------
#include "mytemplate.hpp"
template class A<int>;
int main()
{
return 0;
}
application2.cpp
----------------
#include "mytemplate.h"
void f()
{
A<int> a;
a.f();
}
In short, this is the thing we accomplish.
Now, lets consider traditional C++ programming, where you have a bunch
of translation units which you compile and link together. Why would you
use such a style? It is clearly inconvenient, because you would have to
manually instantiate every function you use somewhere. There is a speed
up in compilation times, because:
- the code is generated only once for each function.
- the template code is not included where it is not needed.
In summary, for traditional C++ programming, the advantage of the
separation is only cosmetic.
Now, lets consider programming with dynamic link libraries. Lets call a
dynamic link library and an executable with a common name module. If you
instantiate a template in module A, and instantiate the same template in
module B, then there exists two copies of the same code. If this isn't
serious enough, there also exists two separate copies of the class
variables. Now, we usually don't like the idea of code replication
(except where we deliberately inline), so we would like to maintain the
code in module A, and let module B use the code from module A. Thus,
there is only one instance of the code and one instance of a class
variable.
Fine, that seems like a solution. But how do we do this in practice?
Because of implicit instantiation, if the template code is present, the
functions will be generated. I am aware of two solutions, from which
the other is what I am proposing:
1) There has been one proposal, the N1448. It suggests to add an
extension to the language, the export to the explicit instantiation. Its
meaning is to say "do not generate an instantiation of this type in any
circumstances, although you have the template code present".
2) Do not give the template code at all, just the class definition (or
function declaration).
Now imagine you are working on a factory, which produces soft rabbits.
It has the following work-flow:
1) The soft rabbits are produced
2) Rabbits are added some clothing to make them more interesting.
3) The clothing is removed and the original soft rabbits sent to
customers.
Your mission is to cut down the costs of producing the soft rabbits. Can
you spot any flaws and improve the workflow? :)
To further provocate, I claim that export is not the right analog for
interface/implementation separation between templates and normal
classes/functions. I say that my separation model is the one.
And why? For this I'd like to note that export does actually two
separations:
1) Separation of interface and implementation
2) Separation of instantion file from the template file (and this is
where we get into the trouble).
The separation in 2 is an unlogical one: there always exists the
dependence between the template code and the instantiating code. I don't
think one should pretend that there is not.
--
Kalle Rutanen
http://kaba.hilvi.org
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]