templates

Discussion in 'C++' started by Rene Ivon Shamberger, Dec 5, 2012.

  1. As I would normally '#include' the header files to a main.cpp I have noticed that I need to '#include' the header and source file when I there is a template in those files. Is this the normal for C++?

    Example of normal include
    // with out a function template
    #include "my_file.hpp"

    void main(){}


    Example of abnormal include
    //With function template
    #include "my_file.hpp"
    #include "my_file.cpp"
    void main(){}

    TIA
    TIA
    Rene Ivon Shamberger, Dec 5, 2012
    #1
    1. Advertising

  2. On 12/5/2012 8:34 AM, Rene Ivon Shamberger wrote:
    > As I would normally '#include' the header files to a main.cpp I have

    noticed that I need to '#include' the header and source file when I
    there is a template in those files. Is this the normal for C++?

    You #include what you want your compiler to see.

    >
    > Example of normal include
    > // with out a function template
    > #include "my_file.hpp"
    >
    > void main(){}


    int main(){}

    >
    >
    > Example of abnormal include
    > //With function template
    > #include "my_file.hpp"
    > #include "my_file.cpp"
    > void main(){}


    Also, see the FAQ.

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Dec 5, 2012
    #2
    1. Advertising

  3. I have double checked this method, and it is fine. However, there is a problem at linker time. Perhaps one of you can do me the honours to check out and let me know what I am doing wrong? Thanks!!

    ---- myclass.hpp -----
    #ifndef ABC_MYCLASS_HPP
    #define ABC_MYCLASS_HPP

    #include <string>

    namespace ABC{
    class myClass{
    private:
    std::string str;
    public:
    MyClass(){str.clear();}
    virtual ~MyClass(){}
    template< typename T> std::string& format( const T& data );

    };//class
    }// name space
    #endif

    ---- myclass.cpp ----
    #ifndef ABC_MYCLASS_HPP
    #include "myclass.hpp"
    #endif
    template< typename T>
    std::string& ABC::MyClass::format(const T& data){
    std::stringstream num;
    num.flush();
    num << data;
    str = num.str();
    return str;
    }

    ---- main.cpp -----
    #include <iostream>
    #include "myclass.hpp"
    int main(){
    ABC::MyClass mc;
    int i = 100;
    std::string text = mc.format(i); //<<-- linker error
    ....

    return 0;
    }


    1>------ Build started: Project: ABC, Configuration: Release Win32 ------
    1> main.cpp
    1>main.obj : error LNK2001: unresolved external symbol "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > & __thiscall ABC::MyClass::format<int>(int const &)" (??$format@H@MyClass@ABC@@QAEAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABH@Z)
    1>{myfolder}\Release\ABC.exe : fatal error LNK1120: 1 unresolved externals
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    Rene Ivon Shamberger, Dec 5, 2012
    #3
  4. On Wed, 05 Dec 2012 06:51:33 -0800, Rene Ivon Shamberger wrote:

    > I have double checked this method, and it is fine. However, there is a
    > problem at linker time. Perhaps one of you can do me the honours to
    > check out and let me know what I am doing wrong? Thanks!!
    >
    > ---- myclass.hpp -----
    > #ifndef ABC_MYCLASS_HPP
    > #define ABC_MYCLASS_HPP
    >
    > #include <string>
    >
    > namespace ABC{
    > class myClass{
    > private:
    > std::string str;
    > public:
    > MyClass(){str.clear();}
    > virtual ~MyClass(){}
    > template< typename T> std::string& format( const T& data );
    >
    > };//class
    > }// name space
    > #endif
    >
    > ---- myclass.cpp ----
    > #ifndef ABC_MYCLASS_HPP
    > #include "myclass.hpp"
    > #endif
    > template< typename T>
    > std::string& ABC::MyClass::format(const T& data){
    > std::stringstream num;
    > num.flush();
    > num << data;
    > str = num.str();
    > return str;
    > }
    >

    Separate compilation of templates is not generally supported by compilers.
    The problem is that the compiler must be able to see in which context a
    template is being used to know which specializations to generate. This is
    not possible with separate compilation, because each source file is
    processed independently from the others, so the information about which
    specializations are needed is not available when processing myclass.cpp

    The typical solutions are
    1. Place all template code in the header
    2. Place the template code in a separate file (often with a .icc or .tcc
    extension) and #include that file at the end of the header.

    Bart v Ingen Schenau
    Bart van Ingen Schenau, Dec 5, 2012
    #4
  5. Outstanding Bart!
    Thanks so much, it works like a charm.
    Rene Ivon Shamberger, Dec 5, 2012
    #5
    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. Fred
    Replies:
    1
    Views:
    594
    Neredbojias
    Sep 26, 2005
  2. John Harrison

    using templates in templates

    John Harrison, Jul 31, 2003, in forum: C++
    Replies:
    8
    Views:
    379
    Torsten Curdt
    Jul 31, 2003
  3. JKop
    Replies:
    3
    Views:
    467
  4. Tom McCallum

    Templates within templates

    Tom McCallum, Aug 4, 2004, in forum: C++
    Replies:
    2
    Views:
    363
    tom_usenet
    Aug 4, 2004
  5. recover
    Replies:
    2
    Views:
    799
    recover
    Jul 25, 2006
Loading...

Share This Page