Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > separating definitions from declarations when using templates

Reply
Thread Tools

separating definitions from declarations when using templates

 
 
aaragon
Guest
Posts: n/a
 
      02-09-2007
Hi everyone,

I've been writing some code and so far I have all the code written in
the .h files in order to avoid the linker errors. I'm using templates.
I wanted to move the implementations to the .cpp files. After some
reading, I found that the only way to do this is to add the actual
template instantiations in the .cpp file. But, how do you do that if
you're not working with built-in types? For example, a template class
might be,

template
<
class Objective,
class StoragePolicy,
int k
>

class ClassA {
....
// declarations and definitions
....
}

How do I separate this into .cpp and .h files if I Objective and
StoragePolicy are defined by the user of the code? In this example,
StoragePolicy is something that I could define (let's say
std::vector), but Objective is an object that the user provides. Is
there a way to get around this? I read also something about using the
"export" keyword but it doesn't seem to work with gnu g++. Any help
will be appreciated.

a^2

 
Reply With Quote
 
 
 
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      02-10-2007
aaragon wrote:

> Hi everyone,
>
> I've been writing some code and so far I have all the code written in
> the .h files in order to avoid the linker errors. I'm using templates.
> I wanted to move the implementations to the .cpp files. After some
> reading, I found that the only way to do this is to add the actual
> template instantiations in the .cpp file. But, how do you do that if
> you're not working with built-in types? For example, a template class
> might be,
>
> template
> <
> class Objective,
> class StoragePolicy,
> int k
>>

> class ClassA {
> ...
> // declarations and definitions
> ...
> }
>
> How do I separate this into .cpp and .h files if I Objective and
> StoragePolicy are defined by the user of the code?


Short answer: you don't.

> In this example,
> StoragePolicy is something that I could define (let's say
> std::vector), but Objective is an object that the user provides. Is
> there a way to get around this? I read also something about using the
> "export" keyword but it doesn't seem to work with gnu g++.


The export keyword is meant for this purpose, however, most compilers don't
support it.

> Any help will be appreciated.


Your options include:

a) leave the implementation code in the header files. This is common
practice.

b) use a compiler that supports "export". This is not common and will render
you code less portable.


Best

Kai-Uwe Bux
 
Reply With Quote
 
 
 
 
aaragon
Guest
Posts: n/a
 
      02-10-2007
On Feb 9, 6:08 pm, Kai-Uwe Bux <(E-Mail Removed)> wrote:
> aaragon wrote:
> > Hi everyone,

>
> > I've been writing some code and so far I have all the code written in
> > the .h files in order to avoid the linker errors. I'm using templates.
> > I wanted to move the implementations to the .cpp files. After some
> > reading, I found that the only way to do this is to add the actual
> > template instantiations in the .cpp file. But, how do you do that if
> > you're not working with built-in types? For example, a template class
> > might be,

>
> > template
> > <
> > class Objective,
> > class StoragePolicy,
> > int k

>
> > class ClassA {
> > ...
> > // declarations and definitions
> > ...
> > }

>
> > How do I separate this into .cpp and .h files if I Objective and
> > StoragePolicy are defined by the user of the code?

>
> Short answer: you don't.
>
> > In this example,
> > StoragePolicy is something that I could define (let's say
> > std::vector), but Objective is an object that the user provides. Is
> > there a way to get around this? I read also something about using the
> > "export" keyword but it doesn't seem to work with gnu g++.

>
> The export keyword is meant for this purpose, however, most compilers don't
> support it.
>
> > Any help will be appreciated.

>
> Your options include:
>
> a) leave the implementation code in the header files. This is common
> practice.
>
> b) use a compiler that supports "export". This is not common and will render
> you code less portable.
>
> Best
>
> Kai-Uwe Bux


Thanks for your reply. I'll go with option a) for now. Best regards.

 
Reply With Quote
 
paul.joseph.davis@gmail.com
Guest
Posts: n/a
 
      02-10-2007
On Feb 9, 6:54 pm, "aaragon" <(E-Mail Removed)> wrote:
> On Feb 9, 6:08 pm, Kai-Uwe Bux <(E-Mail Removed)> wrote:
>
>
>
> > aaragon wrote:
> > > Hi everyone,

>
> > > I've been writing some code and so far I have all the code written in
> > > the .h files in order to avoid the linker errors. I'm using templates.
> > > I wanted to move the implementations to the .cpp files. After some
> > > reading, I found that the only way to do this is to add the actual
> > > template instantiations in the .cpp file. But, how do you do that if
> > > you're not working with built-in types? For example, a template class
> > > might be,

>
> > > template
> > > <
> > > class Objective,
> > > class StoragePolicy,
> > > int k

>
> > > class ClassA {
> > > ...
> > > // declarations and definitions
> > > ...
> > > }

>
> > > How do I separate this into .cpp and .h files if I Objective and
> > > StoragePolicy are defined by the user of the code?

>
> > Short answer: you don't.

>
> > > In this example,
> > > StoragePolicy is something that I could define (let's say
> > > std::vector), but Objective is an object that the user provides. Is
> > > there a way to get around this? I read also something about using the
> > > "export" keyword but it doesn't seem to work with gnu g++.

>
> > The export keyword is meant for this purpose, however, most compilers don't
> > support it.

>
> > > Any help will be appreciated.

>
> > Your options include:

>
> > a) leave the implementation code in the header files. This is common
> > practice.

>
> > b) use a compiler that supports "export". This is not common and will render
> > you code less portable.

>
> > Best

>
> > Kai-Uwe Bux

>
> Thanks for your reply. I'll go with option a) for now. Best regards.



aaragon,

Although this isn't removing it from #included headers, this is a good
way to separate the implementation from definition in files.

/////foo.hh

#ifndef FOO_HH
#define FOO_HH

template< typename TYPE >
void
foo( TYPE val ) ;

#include "foo.tcc"

#endif

////foo.tcc

#include <iostream>

template< typename TYPE >
void
foo( TYPE val )
{
std::cout << val << std::endl ;
}

////main.cc

#include "foo.hh"

int
main( int argc, char* argv[] )
{
foo( 1 ) ;
}

///End of example.

HTH,

Paul Davis

 
Reply With Quote
 
Dave Rahardja
Guest
Posts: n/a
 
      02-10-2007
On 9 Feb 2007 18:04:38 -0800, "(E-Mail Removed)"
<(E-Mail Removed)> wrote:

>On Feb 9, 6:54 pm, "aaragon" <(E-Mail Removed)> wrote:
>> On Feb 9, 6:08 pm, Kai-Uwe Bux <(E-Mail Removed)> wrote:
>>
>>
>>
>> > aaragon wrote:
>> > > Hi everyone,

>>
>> > > I've been writing some code and so far I have all the code written in
>> > > the .h files in order to avoid the linker errors. I'm using templates.
>> > > I wanted to move the implementations to the .cpp files. After some
>> > > reading, I found that the only way to do this is to add the actual
>> > > template instantiations in the .cpp file. But, how do you do that if
>> > > you're not working with built-in types? For example, a template class
>> > > might be,

>>
>> > > template
>> > > <
>> > > class Objective,
>> > > class StoragePolicy,
>> > > int k

>>
>> > > class ClassA {
>> > > ...
>> > > // declarations and definitions
>> > > ...
>> > > }

>>
>> > > How do I separate this into .cpp and .h files if I Objective and
>> > > StoragePolicy are defined by the user of the code?

>>
>> > Short answer: you don't.

>>
>> > > In this example,
>> > > StoragePolicy is something that I could define (let's say
>> > > std::vector), but Objective is an object that the user provides. Is
>> > > there a way to get around this? I read also something about using the
>> > > "export" keyword but it doesn't seem to work with gnu g++.

>>
>> > The export keyword is meant for this purpose, however, most compilers don't
>> > support it.

>>
>> > > Any help will be appreciated.

>>
>> > Your options include:

>>
>> > a) leave the implementation code in the header files. This is common
>> > practice.

>>
>> > b) use a compiler that supports "export". This is not common and will render
>> > you code less portable.

>>
>> > Best

>>
>> > Kai-Uwe Bux

>>
>> Thanks for your reply. I'll go with option a) for now. Best regards.

>
>
>aaragon,
>
>Although this isn't removing it from #included headers, this is a good
>way to separate the implementation from definition in files.
>
>/////foo.hh
>
>#ifndef FOO_HH
>#define FOO_HH
>
>template< typename TYPE >
>void
>foo( TYPE val ) ;
>
>#include "foo.tcc"
>
>#endif
>
>////foo.tcc
>
>#include <iostream>
>
>template< typename TYPE >
>void
>foo( TYPE val )
>{
> std::cout << val << std::endl ;
>}
>
>////main.cc
>
>#include "foo.hh"
>
>int
>main( int argc, char* argv[] )
>{
> foo( 1 ) ;
>}
>
>///End of example.
>
>HTH,
>
>Paul Davis


I would even suggest:

// export_support_begin.hh

#if defined(EXPORT)
#undef EXPORT

#if defined(EXPORT_KEYWORD_SUPPORT)
#define EXPORT export
#else
#define EXPORT
#endif


// export_support_end.hh

#undef EXPORT


// foo.hh

#ifndef FOO_HH
#define FOO_HH

#include "export_support_begin.hh"

EXPORT template< typename TYPE >
void
foo( TYPE val ) ;

#if !defined(EXPORT_KEYWORD_SUPPORT)
#include "foo.tcc"
#endif

#include "export_support_end.hh"

#endif


// foo.tcc

#include <iostream>

#include "foo.hh"
#include "export_support_begin.hh"

EXPORT template< typename TYPE >
void
foo( TYPE val )
{
std::cout << val << std::endl ;
}

#include "export_support_end.hh"


// main.cc

#include "foo.hh"

int
main( int argc, char* argv[] )
{
foo( 1 ) ;
}


That way you can define EXPORT_KEYWORD_SUPPORT on compilers that support the
export keyword (notably Comeau and other compilers that use the EDG front
end).

It is safe to compile foo.tcc even on a noncompliant compiler.

-dr
 
Reply With Quote
 
paul.joseph.davis@gmail.com
Guest
Posts: n/a
 
      02-10-2007
On Feb 9, 10:46 pm, Dave Rahardja <(E-Mail Removed)> wrote:
> On 9 Feb 2007 18:04:38 -0800, "(E-Mail Removed)"
>
>
>
> <(E-Mail Removed)> wrote:
> >On Feb 9, 6:54 pm, "aaragon" <(E-Mail Removed)> wrote:
> >> On Feb 9, 6:08 pm, Kai-Uwe Bux <(E-Mail Removed)> wrote:

>
> >> > aaragon wrote:
> >> > > Hi everyone,

>
> >> > > I've been writing some code and so far I have all the code written in
> >> > > the .h files in order to avoid the linker errors. I'm using templates.
> >> > > I wanted to move the implementations to the .cpp files. After some
> >> > > reading, I found that the only way to do this is to add the actual
> >> > > template instantiations in the .cpp file. But, how do you do that if
> >> > > you're not working with built-in types? For example, a template class
> >> > > might be,

>
> >> > > template
> >> > > <
> >> > > class Objective,
> >> > > class StoragePolicy,
> >> > > int k

>
> >> > > class ClassA {
> >> > > ...
> >> > > // declarations and definitions
> >> > > ...
> >> > > }

>
> >> > > How do I separate this into .cpp and .h files if I Objective and
> >> > > StoragePolicy are defined by the user of the code?

>
> >> > Short answer: you don't.

>
> >> > > In this example,
> >> > > StoragePolicy is something that I could define (let's say
> >> > > std::vector), but Objective is an object that the user provides. Is
> >> > > there a way to get around this? I read also something about using the
> >> > > "export" keyword but it doesn't seem to work with gnu g++.

>
> >> > The export keyword is meant for this purpose, however, most compilers don't
> >> > support it.

>
> >> > > Any help will be appreciated.

>
> >> > Your options include:

>
> >> > a) leave the implementation code in the header files. This is common
> >> > practice.

>
> >> > b) use a compiler that supports "export". This is not common and will render
> >> > you code less portable.

>
> >> > Best

>
> >> > Kai-Uwe Bux

>
> >> Thanks for your reply. I'll go with option a) for now. Best regards.

>
> >aaragon,

>
> >Although this isn't removing it from #included headers, this is a good
> >way to separate the implementation from definition in files.

>
> >/////foo.hh

>
> >#ifndef FOO_HH
> >#define FOO_HH

>
> >template< typename TYPE >
> >void
> >foo( TYPE val ) ;

>
> >#include "foo.tcc"

>
> >#endif

>
> >////foo.tcc

>
> >#include <iostream>

>
> >template< typename TYPE >
> >void
> >foo( TYPE val )
> >{
> > std::cout << val << std::endl ;
> >}

>
> >////main.cc

>
> >#include "foo.hh"

>
> >int
> >main( int argc, char* argv[] )
> >{
> > foo( 1 ) ;
> >}

>
> >///End of example.

>
> >HTH,

>
> >Paul Davis

>
> I would even suggest:
>
> // export_support_begin.hh
>
> #if defined(EXPORT)
> #undef EXPORT
>
> #if defined(EXPORT_KEYWORD_SUPPORT)
> #define EXPORT export
> #else
> #define EXPORT
> #endif
>
> // export_support_end.hh
>
> #undef EXPORT
>
> // foo.hh
>
> #ifndef FOO_HH
> #define FOO_HH
>
> #include "export_support_begin.hh"
>
> EXPORT template< typename TYPE >
> void
> foo( TYPE val ) ;
>
> #if !defined(EXPORT_KEYWORD_SUPPORT)
> #include "foo.tcc"
> #endif
>
> #include "export_support_end.hh"
>
> #endif
>
> // foo.tcc
>
> #include <iostream>
>
> #include "foo.hh"
> #include "export_support_begin.hh"
>
> EXPORT template< typename TYPE >
> void
> foo( TYPE val )
> {
> std::cout << val << std::endl ;
>
> }
>
> #include "export_support_end.hh"
>
> // main.cc
>
> #include "foo.hh"
>
> int
> main( int argc, char* argv[] )
> {
> foo( 1 ) ;
>
> }
>
> That way you can define EXPORT_KEYWORD_SUPPORT on compilers that support the
> export keyword (notably Comeau and other compilers that use the EDG front
> end).
>
> It is safe to compile foo.tcc even on a noncompliant compiler.
>
> -dr



I dunno. That seems like an awful lot of work for rather little pay
off. I'm not entirely certain about how the export keyword works, but
I imagine all this would save is the redundant compilation of a
multiple templates with the same type parameters.

Paul Davis

 
Reply With Quote
 
paul.joseph.davis@gmail.com
Guest
Posts: n/a
 
      02-10-2007
On Feb 10, 3:29 am, "(E-Mail Removed)"
<(E-Mail Removed)> wrote:
> On Feb 9, 10:46 pm, Dave Rahardja <(E-Mail Removed)> wrote:
>
>
>
> > On 9 Feb 2007 18:04:38 -0800, "(E-Mail Removed)"

>
> > <(E-Mail Removed)> wrote:
> > >On Feb 9, 6:54 pm, "aaragon" <(E-Mail Removed)> wrote:
> > >> On Feb 9, 6:08 pm, Kai-Uwe Bux <(E-Mail Removed)> wrote:

>
> > >> > aaragon wrote:
> > >> > > Hi everyone,

>
> > >> > > I've been writing some code and so far I have all the code written in
> > >> > > the .h files in order to avoid the linker errors. I'm using templates.
> > >> > > I wanted to move the implementations to the .cpp files. After some
> > >> > > reading, I found that the only way to do this is to add the actual
> > >> > > template instantiations in the .cpp file. But, how do you do that if
> > >> > > you're not working with built-in types? For example, a template class
> > >> > > might be,

>
> > >> > > template
> > >> > > <
> > >> > > class Objective,
> > >> > > class StoragePolicy,
> > >> > > int k

>
> > >> > > class ClassA {
> > >> > > ...
> > >> > > // declarations and definitions
> > >> > > ...
> > >> > > }

>
> > >> > > How do I separate this into .cpp and .h files if I Objective and
> > >> > > StoragePolicy are defined by the user of the code?

>
> > >> > Short answer: you don't.

>
> > >> > > In this example,
> > >> > > StoragePolicy is something that I could define (let's say
> > >> > > std::vector), but Objective is an object that the user provides. Is
> > >> > > there a way to get around this? I read also something about using the
> > >> > > "export" keyword but it doesn't seem to work with gnu g++.

>
> > >> > The export keyword is meant for this purpose, however, most compilers don't
> > >> > support it.

>
> > >> > > Any help will be appreciated.

>
> > >> > Your options include:

>
> > >> > a) leave the implementation code in the header files. This is common
> > >> > practice.

>
> > >> > b) use a compiler that supports "export". This is not common and will render
> > >> > you code less portable.

>
> > >> > Best

>
> > >> > Kai-Uwe Bux

>
> > >> Thanks for your reply. I'll go with option a) for now. Best regards.

>
> > >aaragon,

>
> > >Although this isn't removing it from #included headers, this is a good
> > >way to separate the implementation from definition in files.

>
> > >/////foo.hh

>
> > >#ifndef FOO_HH
> > >#define FOO_HH

>
> > >template< typename TYPE >
> > >void
> > >foo( TYPE val ) ;

>
> > >#include "foo.tcc"

>
> > >#endif

>
> > >////foo.tcc

>
> > >#include <iostream>

>
> > >template< typename TYPE >
> > >void
> > >foo( TYPE val )
> > >{
> > > std::cout << val << std::endl ;
> > >}

>
> > >////main.cc

>
> > >#include "foo.hh"

>
> > >int
> > >main( int argc, char* argv[] )
> > >{
> > > foo( 1 ) ;
> > >}

>
> > >///End of example.

>
> > >HTH,

>
> > >Paul Davis

>
> > I would even suggest:

>
> > // export_support_begin.hh

>
> > #if defined(EXPORT)
> > #undef EXPORT

>
> > #if defined(EXPORT_KEYWORD_SUPPORT)
> > #define EXPORT export
> > #else
> > #define EXPORT
> > #endif

>
> > // export_support_end.hh

>
> > #undef EXPORT

>
> > // foo.hh

>
> > #ifndef FOO_HH
> > #define FOO_HH

>
> > #include "export_support_begin.hh"

>
> > EXPORT template< typename TYPE >
> > void
> > foo( TYPE val ) ;

>
> > #if !defined(EXPORT_KEYWORD_SUPPORT)
> > #include "foo.tcc"
> > #endif

>
> > #include "export_support_end.hh"

>
> > #endif

>
> > // foo.tcc

>
> > #include <iostream>

>
> > #include "foo.hh"
> > #include "export_support_begin.hh"

>
> > EXPORT template< typename TYPE >
> > void
> > foo( TYPE val )
> > {
> > std::cout << val << std::endl ;

>
> > }

>
> > #include "export_support_end.hh"

>
> > // main.cc

>
> > #include "foo.hh"

>
> > int
> > main( int argc, char* argv[] )
> > {
> > foo( 1 ) ;

>
> > }

>
> > That way you can define EXPORT_KEYWORD_SUPPORT on compilers that support the
> > export keyword (notably Comeau and other compilers that use the EDG front
> > end).

>
> > It is safe to compile foo.tcc even on a noncompliant compiler.

>
> > -dr

>
> I dunno. That seems like an awful lot of work for rather little pay
> off. I'm not entirely certain about how the export keyword works, but
> I imagine all this would save is the redundant compilation of a
> multiple templates with the same type parameters.
>
> Paul Davis


Thought this was an interesting topic I haven't read enough about so I
googled around a bit and found a two articles about export. One for
and one against.

Against:
http://std.dkuug.dk/JTC1/SC22/WG21/d...2003/n1426.pdf

For:
http://www.comeaucomputing.com/iso/promises.html

Personally, I really don't see the motivation for a compiler to
support the feature other than to be fully standards conformant. The
article that was for keeping and requiring export did little to
convince me that export was a Good Thing (TM). In general the argument
seemed to be built on arguments that had little to do with the
theoretical aspects of why export is good and should be kept, instead
focusing on the fact that so much has already been put into it and its
not the only hard feature to implement.

The fact that this feature is so prohibitive to implement that major
compiler vendors aren't supporting it says something to me. I mean,
these people write *compilers* for a living. Although anecdotal and
trivial, how many features have made major compilers balk at
supporting them due to the prohibitively complex nature? I'd imagine
thats a fairly short list.

>From what I've seen, all the 'odd' rules (e.g. koenig lookup) that

make up C++ have a very sound theoretical reason behind them. I
haven't found a good reason for supporting export other than the
original topic of separating template implementation from definition.

As always though, if someone can show me an example that will
absolutely not work without export I'd be happy to change my tune.
But until then, it seems like a waste of effort for compiler
developers.

Paul Davis

 
Reply With Quote
 
aaragon
Guest
Posts: n/a
 
      02-11-2007
On Feb 10, 4:15 am, "(E-Mail Removed)"
<(E-Mail Removed)> wrote:
> On Feb 10, 3:29 am, "(E-Mail Removed)"
>
>
>
> <(E-Mail Removed)> wrote:
> > On Feb 9, 10:46 pm, Dave Rahardja <(E-Mail Removed)> wrote:

>
> > > On 9 Feb 2007 18:04:38 -0800, "(E-Mail Removed)"

>
> > > <(E-Mail Removed)> wrote:
> > > >On Feb 9, 6:54 pm, "aaragon" <(E-Mail Removed)> wrote:
> > > >> On Feb 9, 6:08 pm, Kai-Uwe Bux <(E-Mail Removed)> wrote:

>
> > > >> > aaragon wrote:
> > > >> > > Hi everyone,

>
> > > >> > > I've been writing some code and so far I have all the code written in
> > > >> > > the .h files in order to avoid the linker errors. I'm using templates.
> > > >> > > I wanted to move the implementations to the .cpp files. After some
> > > >> > > reading, I found that the only way to do this is to add the actual
> > > >> > > template instantiations in the .cpp file. But, how do you do that if
> > > >> > > you're not working with built-in types? For example, a template class
> > > >> > > might be,

>
> > > >> > > template
> > > >> > > <
> > > >> > > class Objective,
> > > >> > > class StoragePolicy,
> > > >> > > int k

>
> > > >> > > class ClassA {
> > > >> > > ...
> > > >> > > // declarations and definitions
> > > >> > > ...
> > > >> > > }

>
> > > >> > > How do I separate this into .cpp and .h files if I Objective and
> > > >> > > StoragePolicy are defined by the user of the code?

>
> > > >> > Short answer: you don't.

>
> > > >> > > In this example,
> > > >> > > StoragePolicy is something that I could define (let's say
> > > >> > > std::vector), but Objective is an object that the user provides. Is
> > > >> > > there a way to get around this? I read also something about using the
> > > >> > > "export" keyword but it doesn't seem to work with gnu g++.

>
> > > >> > The export keyword is meant for this purpose, however, most compilers don't
> > > >> > support it.

>
> > > >> > > Any help will be appreciated.

>
> > > >> > Your options include:

>
> > > >> > a) leave the implementation code in the header files. This is common
> > > >> > practice.

>
> > > >> > b) use a compiler that supports "export". This is not common and will render
> > > >> > you code less portable.

>
> > > >> > Best

>
> > > >> > Kai-Uwe Bux

>
> > > >> Thanks for your reply. I'll go with option a) for now. Best regards.

>
> > > >aaragon,

>
> > > >Although this isn't removing it from #included headers, this is a good
> > > >way to separate the implementation from definition in files.

>
> > > >/////foo.hh

>
> > > >#ifndef FOO_HH
> > > >#define FOO_HH

>
> > > >template< typename TYPE >
> > > >void
> > > >foo( TYPE val ) ;

>
> > > >#include "foo.tcc"

>
> > > >#endif

>
> > > >////foo.tcc

>
> > > >#include <iostream>

>
> > > >template< typename TYPE >
> > > >void
> > > >foo( TYPE val )
> > > >{
> > > > std::cout << val << std::endl ;
> > > >}

>
> > > >////main.cc

>
> > > >#include "foo.hh"

>
> > > >int
> > > >main( int argc, char* argv[] )
> > > >{
> > > > foo( 1 ) ;
> > > >}

>
> > > >///End of example.

>
> > > >HTH,

>
> > > >Paul Davis

>
> > > I would even suggest:

>
> > > // export_support_begin.hh

>
> > > #if defined(EXPORT)
> > > #undef EXPORT

>
> > > #if defined(EXPORT_KEYWORD_SUPPORT)
> > > #define EXPORT export
> > > #else
> > > #define EXPORT
> > > #endif

>
> > > // export_support_end.hh

>
> > > #undef EXPORT

>
> > > // foo.hh

>
> > > #ifndef FOO_HH
> > > #define FOO_HH

>
> > > #include "export_support_begin.hh"

>
> > > EXPORT template< typename TYPE >
> > > void
> > > foo( TYPE val ) ;

>
> > > #if !defined(EXPORT_KEYWORD_SUPPORT)
> > > #include "foo.tcc"
> > > #endif

>
> > > #include "export_support_end.hh"

>
> > > #endif

>
> > > // foo.tcc

>
> > > #include <iostream>

>
> > > #include "foo.hh"
> > > #include "export_support_begin.hh"

>
> > > EXPORT template< typename TYPE >
> > > void
> > > foo( TYPE val )
> > > {
> > > std::cout << val << std::endl ;

>
> > > }

>
> > > #include "export_support_end.hh"

>
> > > // main.cc

>
> > > #include "foo.hh"

>
> > > int
> > > main( int argc, char* argv[] )
> > > {
> > > foo( 1 ) ;

>
> > > }

>
> > > That way you can define EXPORT_KEYWORD_SUPPORT on compilers that support the
> > > export keyword (notably Comeau and other compilers that use the EDG front
> > > end).

>
> > > It is safe to compile foo.tcc even on a noncompliant compiler.

>
> > > -dr

>
> > I dunno. That seems like an awful lot of work for rather little pay
> > off. I'm not entirely certain about how the export keyword works, but
> > I imagine all this would save is the redundant compilation of a
> > multiple templates with the same type parameters.

>
> > Paul Davis

>
> Thought this was an interesting topic I haven't read enough about so I
> googled around a bit and found a two articles about export. One for
> and one against.
>
> Against:http://std.dkuug.dk/JTC1/SC22/WG21/d...2003/n1426.pdf
>
> For:http://www.comeaucomputing.com/iso/promises.html
>
> Personally, I really don't see the motivation for a compiler to
> support the feature other than to be fully standards conformant. The
> article that was for keeping and requiring export did little to
> convince me that export was a Good Thing (TM). In general the argument
> seemed to be built on arguments that had little to do with the
> theoretical aspects of why export is good and should be kept, instead
> focusing on the fact that so much has already been put into it and its
> not the only hard feature to implement.
>
> The fact that this feature is so prohibitive to implement that major
> compiler vendors aren't supporting it says something to me. I mean,
> these people write *compilers* for a living. Although anecdotal and
> trivial, how many features have made major compilers balk at
> supporting them due to the prohibitively complex nature? I'd imagine
> thats a fairly short list.
>
> >From what I've seen, all the 'odd' rules (e.g. koenig lookup) that

>
> make up C++ have a very sound theoretical reason behind them. I
> haven't found a good reason for supporting export other than the
> original topic of separating template implementation from definition.
>
> As always though, if someone can show me an example that will
> absolutely not work without export I'd be happy to change my tune.
> But until then, it seems like a waste of effort for compiler
> developers.
>
> Paul Davis


Thank you guys for all your insight on this. I appreciate it a lot.

 
Reply With Quote
 
aaragon
Guest
Posts: n/a
 
      02-11-2007
On Feb 9, 8:04 pm, "(E-Mail Removed)"
<(E-Mail Removed)> wrote:
> On Feb 9, 6:54 pm, "aaragon" <(E-Mail Removed)> wrote:
>
>
>
> > On Feb 9, 6:08 pm, Kai-Uwe Bux <(E-Mail Removed)> wrote:

>
> > > aaragon wrote:
> > > > Hi everyone,

>
> > > > I've been writing some code and so far I have all the code written in
> > > > the .h files in order to avoid the linker errors. I'm using templates.
> > > > I wanted to move the implementations to the .cpp files. After some
> > > > reading, I found that the only way to do this is to add the actual
> > > > template instantiations in the .cpp file. But, how do you do that if
> > > > you're not working with built-in types? For example, a template class
> > > > might be,

>
> > > > template
> > > > <
> > > > class Objective,
> > > > class StoragePolicy,
> > > > int k

>
> > > > class ClassA {
> > > > ...
> > > > // declarations and definitions
> > > > ...
> > > > }

>
> > > > How do I separate this into .cpp and .h files if I Objective and
> > > > StoragePolicy are defined by the user of the code?

>
> > > Short answer: you don't.

>
> > > > In this example,
> > > > StoragePolicy is something that I could define (let's say
> > > > std::vector), but Objective is an object that the user provides. Is
> > > > there a way to get around this? I read also something about using the
> > > > "export" keyword but it doesn't seem to work with gnu g++.

>
> > > The export keyword is meant for this purpose, however, most compilers don't
> > > support it.

>
> > > > Any help will be appreciated.

>
> > > Your options include:

>
> > > a) leave the implementation code in the header files. This is common
> > > practice.

>
> > > b) use a compiler that supports "export". This is not common and will render
> > > you code less portable.

>
> > > Best

>
> > > Kai-Uwe Bux

>
> > Thanks for your reply. I'll go with option a) for now. Best regards.

>
> aaragon,
>
> Although this isn't removing it from #included headers, this is a good
> way to separate the implementation from definition in files.
>
> /////foo.hh
>
> #ifndef FOO_HH
> #define FOO_HH
>
> template< typename TYPE >
> void
> foo( TYPE val ) ;
>
> #include "foo.tcc"
>
> #endif
>
> ////foo.tcc
>
> #include <iostream>
>
> template< typename TYPE >
> void
> foo( TYPE val )
> {
> std::cout << val << std::endl ;
>
> }
>
> ////main.cc
>
> #include "foo.hh"
>
> int
> main( int argc, char* argv[] )
> {
> foo( 1 ) ;
>
> }
>
> ///End of example.
>
> HTH,
>
> Paul Davis


Paul,

I've been trying to use your approach but I run into problems. When I
include the .cxx file at the end of the .h file then I receive the
compilation error:

file.cxx:9: error: redefinition of 'void ClassA<Objective,
StoragePolicy, k>::initialize()'
file.cxx:9: error: 'void ClassA<Objective, StoragePolicy,
k>::initialize()' previously declared here

I figured that this is because in the .cxx file I had the include of
the .h file so I was actually including the .cxx file twice. I removed
that include in the .cxx file and now the error is

file.cxx:9: error: expected initializer before '<' token

I have no clue why I have this message. I thought that it may be
because I need to compile the .h file instead of the .cxx file in the
Makefile but that doesn't make sense. Any suggestions?

a^2

 
Reply With Quote
 
paul.joseph.davis@gmail.com
Guest
Posts: n/a
 
      02-12-2007
On Feb 11, 2:35 pm, "aaragon" <(E-Mail Removed)> wrote:
> On Feb 9, 8:04 pm, "(E-Mail Removed)"
>
>
>
> <(E-Mail Removed)> wrote:
> > On Feb 9, 6:54 pm, "aaragon" <(E-Mail Removed)> wrote:

>
> > > On Feb 9, 6:08 pm, Kai-Uwe Bux <(E-Mail Removed)> wrote:

>
> > > > aaragon wrote:
> > > > > Hi everyone,

>
> > > > > I've been writing some code and so far I have all the code written in
> > > > > the .h files in order to avoid the linker errors. I'm using templates.
> > > > > I wanted to move the implementations to the .cpp files. After some
> > > > > reading, I found that the only way to do this is to add the actual
> > > > > template instantiations in the .cpp file. But, how do you do that if
> > > > > you're not working with built-in types? For example, a template class
> > > > > might be,

>
> > > > > template
> > > > > <
> > > > > class Objective,
> > > > > class StoragePolicy,
> > > > > int k

>
> > > > > class ClassA {
> > > > > ...
> > > > > // declarations and definitions
> > > > > ...
> > > > > }

>
> > > > > How do I separate this into .cpp and .h files if I Objective and
> > > > > StoragePolicy are defined by the user of the code?

>
> > > > Short answer: you don't.

>
> > > > > In this example,
> > > > > StoragePolicy is something that I could define (let's say
> > > > > std::vector), but Objective is an object that the user provides. Is
> > > > > there a way to get around this? I read also something about using the
> > > > > "export" keyword but it doesn't seem to work with gnu g++.

>
> > > > The export keyword is meant for this purpose, however, most compilers don't
> > > > support it.

>
> > > > > Any help will be appreciated.

>
> > > > Your options include:

>
> > > > a) leave the implementation code in the header files. This is common
> > > > practice.

>
> > > > b) use a compiler that supports "export". This is not common and will render
> > > > you code less portable.

>
> > > > Best

>
> > > > Kai-Uwe Bux

>
> > > Thanks for your reply. I'll go with option a) for now. Best regards.

>
> > aaragon,

>
> > Although this isn't removing it from #included headers, this is a good
> > way to separate the implementation from definition in files.

>
> > /////foo.hh

>
> > #ifndef FOO_HH
> > #define FOO_HH

>
> > template< typename TYPE >
> > void
> > foo( TYPE val ) ;

>
> > #include "foo.tcc"

>
> > #endif

>
> > ////foo.tcc

>
> > #include <iostream>

>
> > template< typename TYPE >
> > void
> > foo( TYPE val )
> > {
> > std::cout << val << std::endl ;

>
> > }

>
> > ////main.cc

>
> > #include "foo.hh"

>
> > int
> > main( int argc, char* argv[] )
> > {
> > foo( 1 ) ;

>
> > }

>
> > ///End of example.

>
> > HTH,

>
> > Paul Davis

>
> Paul,
>
> I've been trying to use your approach but I run into problems. When I
> include the .cxx file at the end of the .h file then I receive the
> compilation error:
>
> file.cxx:9: error: redefinition of 'void ClassA<Objective,
> StoragePolicy, k>::initialize()'
> file.cxx:9: error: 'void ClassA<Objective, StoragePolicy,
> k>::initialize()' previously declared here
>
> I figured that this is because in the .cxx file I had the include of
> the .h file so I was actually including the .cxx file twice. I removed
> that include in the .cxx file and now the error is
>
> file.cxx:9: error: expected initializer before '<' token
>
> I have no clue why I have this message. I thought that it may be
> because I need to compile the .h file instead of the .cxx file in the
> Makefile but that doesn't make sense. Any suggestions?
>
> a^2



Aaragon,

I can't tell for sure without actual file contents, but you're not
including code that just 'uses' the template right?

Ie, your included template file should *only* contain functions and/or
classes that are templates. As you found out, you should also only
included the templated header file by including the corresponding
header.

Your problem is a syntax error. I couldn't tell you why without
looking at the actual source.

HTH,

Paul

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Templates: separating interface from implemenation barcaroller C++ 3 07-16-2009 04:01 PM
how to Specializations of function Templates or Overloading Function templates with Templates ? recover C++ 2 07-25-2006 02:55 AM
How to model definitions and declarations of a programming language? Rikard Land XML 0 10-19-2004 10:23 AM
Templates templates templates JKop C++ 3 07-21-2004 11:44 AM
Declarations and Definitions in One Header Steven T. Hatton C++ 4 04-25-2004 10:24 AM



Advertisments