separating definitions from declarations when using templates

Discussion in 'C++' started by aaragon, Feb 9, 2007.

  1. aaragon

    aaragon Guest

    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
     
    aaragon, Feb 9, 2007
    #1
    1. Advertising

  2. aaragon

    Kai-Uwe Bux Guest

    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
     
    Kai-Uwe Bux, Feb 10, 2007
    #2
    1. Advertising

  3. aaragon

    aaragon Guest

    On Feb 9, 6:08 pm, Kai-Uwe Bux <> 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, Feb 10, 2007
    #3
  4. aaragon

    Guest

    On Feb 9, 6:54 pm, "aaragon" <> wrote:
    > On Feb 9, 6:08 pm, Kai-Uwe Bux <> 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
     
    , Feb 10, 2007
    #4
  5. On 9 Feb 2007 18:04:38 -0800, ""
    <> wrote:

    >On Feb 9, 6:54 pm, "aaragon" <> wrote:
    >> On Feb 9, 6:08 pm, Kai-Uwe Bux <> 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
     
    Dave Rahardja, Feb 10, 2007
    #5
  6. aaragon

    Guest

    On Feb 9, 10:46 pm, Dave Rahardja <> wrote:
    > On 9 Feb 2007 18:04:38 -0800, ""
    >
    >
    >
    > <> wrote:
    > >On Feb 9, 6:54 pm, "aaragon" <> wrote:
    > >> On Feb 9, 6:08 pm, Kai-Uwe Bux <> 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
     
    , Feb 10, 2007
    #6
  7. aaragon

    Guest

    On Feb 10, 3:29 am, ""
    <> wrote:
    > On Feb 9, 10:46 pm, Dave Rahardja <> wrote:
    >
    >
    >
    > > On 9 Feb 2007 18:04:38 -0800, ""

    >
    > > <> wrote:
    > > >On Feb 9, 6:54 pm, "aaragon" <> wrote:
    > > >> On Feb 9, 6:08 pm, Kai-Uwe Bux <> 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/docs/papers/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
     
    , Feb 10, 2007
    #7
  8. aaragon

    aaragon Guest

    On Feb 10, 4:15 am, ""
    <> wrote:
    > On Feb 10, 3:29 am, ""
    >
    >
    >
    > <> wrote:
    > > On Feb 9, 10:46 pm, Dave Rahardja <> wrote:

    >
    > > > On 9 Feb 2007 18:04:38 -0800, ""

    >
    > > > <> wrote:
    > > > >On Feb 9, 6:54 pm, "aaragon" <> wrote:
    > > > >> On Feb 9, 6:08 pm, Kai-Uwe Bux <> 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/docs/papers/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.
     
    aaragon, Feb 11, 2007
    #8
  9. aaragon

    aaragon Guest

    On Feb 9, 8:04 pm, ""
    <> wrote:
    > On Feb 9, 6:54 pm, "aaragon" <> wrote:
    >
    >
    >
    > > On Feb 9, 6:08 pm, Kai-Uwe Bux <> 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, Feb 11, 2007
    #9
  10. aaragon

    Guest

    On Feb 11, 2:35 pm, "aaragon" <> wrote:
    > On Feb 9, 8:04 pm, ""
    >
    >
    >
    > <> wrote:
    > > On Feb 9, 6:54 pm, "aaragon" <> wrote:

    >
    > > > On Feb 9, 6:08 pm, Kai-Uwe Bux <> 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
     
    , Feb 12, 2007
    #10
  11. aaragon

    aaragon Guest

    On Feb 11, 7:53 pm, ""
    <> wrote:
    > On Feb 11, 2:35 pm, "aaragon" <> wrote:
    >
    >
    >
    > > On Feb 9, 8:04 pm, ""

    >
    > > <> wrote:
    > > > On Feb 9, 6:54 pm, "aaragon" <> wrote:

    >
    > > > > On Feb 9, 6:08 pm, Kai-Uwe Bux <> 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


    Well, I have all my code written in the .h files. Now, to try your
    approach, I separated the definition of one function and it compiled
    just fine when both the declaration AND the definition were on the .h
    file. Something like this works fine:

    // file.h
    #ifndef CLASS_A_
    #define CLASS_A_
    template
    <
    class Objective,
    class StoragePolicy,
    int k
    >

    class ClassA{
    void initialize();
    }

    template
    <
    class Objective,
    class StoragePolicy,
    int k
    >

    void ClassA<Objective,StoragePolicy,k>::initialize()
    {
    // do something to initialize
    }

    #endif

    // file.cpp
    #include "file.h"
    // file has nothing, everything defined in the .h file to avoid
    linking problems


    This works fine, it compiles and everything. Then, when I move the
    code to the .cpp file it looks like this:

    // file.h
    #ifndef CLASS_A_
    #define CLASS_A_
    template
    <
    class Objective,
    class StoragePolicy,
    int k
    >

    class ClassA{
    void initialize();
    }
    #include "file.cpp"
    #endif

    // file.cpp
    template
    <
    class Objective,
    class StoragePolicy,
    int k
    >

    void ClassA<Objective,StoragePolicy,k>::initialize()
    {
    // do something to initialize
    }

    Then I got this message
    file.cpp:8: error: expected initializer before '<' token

    I'm using autotools to produce the make file, and the Makefile.am
    looks like

    h_sources = file.h
    cxx_sources = file.cpp

    noinst_PROGRAMS = test.out
    test_out_SOURCES = main.cxx

    Maybe I should compile the .h file instead? I don't know what's going
    on.
     
    aaragon, Feb 13, 2007
    #11
  12. aaragon

    Marcus Kwok Guest

    aaragon <> wrote:
    > Well, I have all my code written in the .h files. Now, to try your
    > approach, I separated the definition of one function and it compiled
    > just fine when both the declaration AND the definition were on the .h
    > file. Something like this works fine:


    [working code redacted]

    > This works fine, it compiles and everything. Then, when I move the
    > code to the .cpp file it looks like this:
    >
    > // file.h
    > #ifndef CLASS_A_
    > #define CLASS_A_
    > template
    > <
    > class Objective,
    > class StoragePolicy,
    > int k
    >>

    > class ClassA{
    > void initialize();
    > }
    > #include "file.cpp"
    > #endif
    >
    > // file.cpp
    > template
    > <
    > class Objective,
    > class StoragePolicy,
    > int k
    >>

    > void ClassA<Objective,StoragePolicy,k>::initialize()


    Here, I believe you do not need to specify the template parameters
    again, since you specified them in the lines above this.

    > {
    > // do something to initialize
    > }
    >
    > Then I got this message
    > file.cpp:8: error: expected initializer before '<' token


    This is probably what the error is telling you (hint: what is line 8 in
    file.cpp?).

    --
    Marcus Kwok
    Replace 'invalid' with 'net' to reply
     
    Marcus Kwok, Feb 13, 2007
    #12
  13. aaragon

    aaragon Guest

    On Feb 13, 12:53 pm, (Marcus Kwok) wrote:
    > aaragon <> wrote:
    > > Well, I have all my code written in the .h files. Now, to try your
    > > approach, I separated the definition of one function and it compiled
    > > just fine when both the declaration AND the definition were on the .h
    > > file. Something like this works fine:

    >
    > [working code redacted]
    >
    >
    >
    > > This works fine, it compiles and everything. Then, when I move the
    > > code to the .cpp file it looks like this:

    >
    > > // file.h
    > > #ifndef CLASS_A_
    > > #define CLASS_A_
    > > template
    > > <
    > > class Objective,
    > > class StoragePolicy,
    > > int k

    >
    > > class ClassA{
    > > void initialize();
    > > }
    > > #include "file.cpp"
    > > #endif

    >
    > > // file.cpp
    > > template
    > > <
    > > class Objective,
    > > class StoragePolicy,
    > > int k

    >
    > > void ClassA<Objective,StoragePolicy,k>::initialize()

    >
    > Here, I believe you do not need to specify the template parameters
    > again, since you specified them in the lines above this.
    >
    > > {
    > > // do something to initialize
    > > }

    >
    > > Then I got this message
    > > file.cpp:8: error: expected initializer before '<' token

    >
    > This is probably what the error is telling you (hint: what is line 8 in
    > file.cpp?).
    >
    > --
    > Marcus Kwok
    > Replace 'invalid' with 'net' to reply


    Well, I removed the <..> but I had other errors. You have to include
    the <..> in the definition, at least with g++. The funny thing is that
    I was able to compile at last! I just changed the Makefile.am so I
    have

    h_sources = file.h
    cxx_sources = file.h

    noinst_PROGRAMS = test.out
    test_out_SOURCES = main.cxx

    It was what I thought, I have to compile the .h file! I mean, if I
    compile the .cpp file, there is no #include "file.h" file on the top
    so the compiler never looks for that file. On the other hand, when
    compiling the file.h, there is an #include "file.cpp" at the end so
    everything is looked up by the compiler. Now, what's bothering me is
    that this is a bad fix. It doesn't make sense to compile header files,
    does it? However, it works and I don't need to deal with export
    keywords or having ALL in the .h files.
    Any other suggestions?
     
    aaragon, Feb 13, 2007
    #13
  14. aaragon

    Marcus Kwok Guest

    aaragon <> wrote:
    > This works fine, it compiles and everything. Then, when I move the
    > code to the .cpp file it looks like this:
    >
    > // file.h
    > #ifndef CLASS_A_
    > #define CLASS_A_
    > template
    > <
    > class Objective,
    > class StoragePolicy,
    > int k
    >>

    > class ClassA{
    > void initialize();
    > }
    > #include "file.cpp"
    > #endif
    >
    > // file.cpp
    > template
    > <
    > class Objective,
    > class StoragePolicy,
    > int k
    >>

    > void ClassA<Objective,StoragePolicy,k>::initialize()
    > {
    > // do something to initialize
    > }
    >
    > Then I got this message
    > file.cpp:8: error: expected initializer before '<' token
    >
    > I'm using autotools to produce the make file, and the Makefile.am
    > looks like
    >
    > h_sources = file.h
    > cxx_sources = file.cpp
    >
    > noinst_PROGRAMS = test.out
    > test_out_SOURCES = main.cxx
    >
    > Maybe I should compile the .h file instead? I don't know what's going
    > on.


    Sorry it took so long to reply.

    OK, my original example was flawed. This compiles and links fine for
    me:

    // template.h
    #ifndef CLASS_A_
    #define CLASS_A_

    template
    <
    class Objective,
    class StoragePolicy,
    int k
    >

    class ClassA {
    void initialize();
    };

    #include "template.cpp"

    #endif


    // template.cpp
    #include "template.h"

    template
    <
    class Objective,
    class StoragePolicy,
    int k
    >

    void ClassA<Objective, StoragePolicy, k>::initialize()
    {
    // do something to initialize
    }


    // usage.cpp
    #include "template.h"

    int main()
    {
    ClassA<int, int, 1> a;
    }


    Then, you only need to compile usage.cpp. You do not need to explicitly
    compile template.cpp by itself, which probably won't do you any good
    unless you use the "export" keyword AND your compiler supports this
    keyword (most don't).

    The main point of this is just to have the implementation of your
    templates in a separate file. You don't actually need to compile
    template.cpp until you instantiate the template, which happens when you
    use it. At that point, the definitions must be known, so they get
    pulled in by #include "template.h" (which implicitly #includes
    "template.cpp").

    --
    Marcus Kwok
    Replace 'invalid' with 'net' to reply
     
    Marcus Kwok, Feb 16, 2007
    #14
  15. aaragon

    Guest

    On Feb 16, 2:10 pm, (Marcus Kwok) wrote:
    > aaragon <> wrote:
    > > This works fine, it compiles and everything. Then, when I move the
    > > code to the .cpp file it looks like this:

    >
    > > // file.h
    > > #ifndef CLASS_A_
    > > #define CLASS_A_
    > > template
    > > <
    > > class Objective,
    > > class StoragePolicy,
    > > int k

    >
    > > class ClassA{
    > > void initialize();
    > > }
    > > #include "file.cpp"
    > > #endif

    >
    > > // file.cpp
    > > template
    > > <
    > > class Objective,
    > > class StoragePolicy,
    > > int k

    >
    > > void ClassA<Objective,StoragePolicy,k>::initialize()
    > > {
    > > // do something to initialize
    > > }

    >
    > > Then I got this message
    > > file.cpp:8: error: expected initializer before '<' token

    >
    > > I'm using autotools to produce the make file, and the Makefile.am
    > > looks like

    >
    > > h_sources = file.h
    > > cxx_sources = file.cpp

    >
    > > noinst_PROGRAMS = test.out
    > > test_out_SOURCES = main.cxx

    >
    > > Maybe I should compile the .h file instead? I don't know what's going
    > > on.

    >
    > Sorry it took so long to reply.
    >
    > OK, my original example was flawed. This compiles and links fine for
    > me:
    >
    > // template.h
    > #ifndef CLASS_A_
    > #define CLASS_A_
    >
    > template
    > <
    > class Objective,
    > class StoragePolicy,
    > int k
    >
    > class ClassA {
    > void initialize();
    >
    > };
    >
    > #include "template.cpp"
    >
    > #endif
    >
    > // template.cpp
    > #include "template.h"
    >


    Just a minor point, but you probably don't need to #include the header
    that #include's this template source file.

    > template
    > <
    > class Objective,
    > class StoragePolicy,
    > int k
    >
    > void ClassA<Objective, StoragePolicy, k>::initialize()
    > {
    > // do something to initialize
    >
    > }
    >
    > // usage.cpp
    > #include "template.h"
    >
    > int main()
    > {
    > ClassA<int, int, 1> a;
    >
    > }
    >
    > Then, you only need to compile usage.cpp. You do not need to explicitly
    > compile template.cpp by itself, which probably won't do you any good
    > unless you use the "export" keyword AND your compiler supports this
    > keyword (most don't).
    >
    > The main point of this is just to have the implementation of your
    > templates in a separate file. You don't actually need to compile
    > template.cpp until you instantiate the template, which happens when you
    > use it. At that point, the definitions must be known, so they get
    > pulled in by #include "template.h" (which implicitly #includes
    > "template.cpp").
    >


    Exactly. Remember, we're not compiling template.cpp into a '.o' file
    here. I specifically use a different extension for template definition
    files (.tcc) to indicate that it shouldn't be compiled independantly.
    This is just used so that you don't end up with template headers that
    are thousands of lines long.

    > --
    > Marcus Kwok
    > Replace 'invalid' with 'net' to reply


    HTH,
    Paul Davis
     
    , Feb 17, 2007
    #15
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rikard Land
    Replies:
    0
    Views:
    358
    Rikard Land
    Oct 19, 2004
  2. Steven T. Hatton

    Declarations and Definitions in One Header

    Steven T. Hatton, Apr 25, 2004, in forum: C++
    Replies:
    4
    Views:
    340
    Steven T. Hatton
    Apr 25, 2004
  3. Chris Gordon-Smith

    Declarations and Definitions: Grammar

    Chris Gordon-Smith, Oct 3, 2004, in forum: C++
    Replies:
    2
    Views:
    394
    Gary Labowitz
    Oct 3, 2004
  4. Jess
    Replies:
    15
    Views:
    521
  5. barcaroller
    Replies:
    3
    Views:
    305
    red floyd
    Jul 16, 2009
Loading...

Share This Page