Separate Template Definition I wrote class Data in header. The C++Compiler compiled without errors.

Discussion in 'C++' started by Immortal Nephi, Jul 29, 2010.

  1. I wrote class Data in header. The C++ Compiler compiled without
    errors. I decided to move all member functions into source code
    because they are for implementation. I do not like that they are
    placed in class body.

    I got error message:

    Linking...
    Main.obj : error LNK2001: unresolved external symbol "public:
    __thiscall Data<unsigned char>::eek:perator unsigned char(void)" (??B?
    $Data@E@@QAEEXZ)
    C:\Main.exe : fatal error LNK1120: 1 unresolved externals

    Could be problem with member function cast operator. All other
    member functions complied without any problems.

    // Data.h
    #if !defined(DATA_H )
    #define DATA_H

    template< typename T >
    class Data {
    public:
    Data();
    ~Data();

    operator unsigned char ();

    private:
    unsigned char x;
    };

    #endif // end macro !defined( DATA_H )



    // Data.cpp

    template< typename T >
    Data< T >::Data() : x( 5 ) {}

    template
    Data< unsigned char >::Data();


    template< typename T >
    Data< T >::~Data() {}

    template
    Data< unsigned char >::~Data();


    // Error unresolved linkage
    template< typename T >
    Data< T >::eek:perator unsigned char () {
    return x;
    }

    template
    Data< unsigned char >::eek:perator unsigned char ();



    // main.cpp

    int main() {
    Data< unsigned char> data;
    unsigned char x = data;

    return 0;
    }
    Immortal Nephi, Jul 29, 2010
    #1
    1. Advertising

  2. Immortal Nephi

    Jonathan Lee Guest

    Re: Separate Template Definition I wrote class Data in header. TheC++ Compiler compiled without errors. I decided to move all member functionsinto source code because they are for implementation. I do not like that theyare placed in class body.

    On Jul 29, 12:39 pm, Immortal Nephi <>
    wrote:
    >         I wrote class Data in header.  The C++ Compiler compiled without
    > errors.  I decided to move all member functions into source code
    > because they are for implementation.  I do not like that they are
    > placed in class body.
    >
    >         I got error message:
    >
    > Linking...
    > Main.obj : error LNK2001: unresolved external symbol "public:
    > __thiscall Data<unsigned char>::eek:perator unsigned char(void)" (??B?
    > $Data@E@@QAEEXZ)
    > C:\Main.exe : fatal error LNK1120: 1 unresolved externals
    >
    >         Could be problem with member function cast operator.  All other
    > member functions complied without any problems.


    GCC compiled this without a complaint, so it's legal-ish (?).
    BUT you have 3 specializations declared in data.cpp without
    definitions. Maybe MS is expecting the definitions.

    (I actually have no idea if this is legal or not since I've
    never declared a specialization and not immediately implemented
    it).

    --Jonathan
    Jonathan Lee, Jul 29, 2010
    #2
    1. Advertising

  3. Re: Separate Template Definition I wrote class Data in header. TheC++ Compiler compiled without errors. I decided to move all member functionsinto source code because they are for implementation. I do not like that theyare placed in class body.

    On Jul 29, 12:31 pm, Jonathan Lee <> wrote:
    > On Jul 29, 12:39 pm, Immortal Nephi <>
    > wrote:
    >
    > >         I wrote class Data in header.  The C++ Compiler compiled without
    > > errors.  I decided to move all member functions into source code
    > > because they are for implementation.  I do not like that they are
    > > placed in class body.

    >
    > >         I got error message:

    >
    > > Linking...
    > > Main.obj : error LNK2001: unresolved external symbol "public:
    > > __thiscall Data<unsigned char>::eek:perator unsigned char(void)" (??B?
    > > $Data@E@@QAEEXZ)
    > > C:\Main.exe : fatal error LNK1120: 1 unresolved externals

    >
    > >         Could be problem with member function cast operator.  All other
    > > member functions complied without any problems.

    >
    > GCC compiled this without a complaint, so it's legal-ish (?).
    > BUT you have 3 specializations declared in data.cpp without
    > definitions. Maybe MS is expecting the definitions.
    >
    > (I actually have no idea if this is legal or not since I've
    > never declared a specialization and not immediately implemented
    > it).


    Yes, I use Microsoft Visual C++ Compiler 9.0. Does anyone experience
    that way?
    Each member function can have more than one specification such as
    char, short, long, enum, etc. I put 15 enum specifications in EACH
    member functions on source code. Microsoft Visual C++ Compiler
    compiled successfully without any problems, but only one problem is
    the cast operator member function.
    Immortal Nephi, Jul 29, 2010
    #3
  4. Immortal Nephi

    Jonathan Lee Guest

    Re: Separate Template Definition I wrote class Data in header. TheC++ Compiler compiled without errors. I decided to move all member functionsinto source code because they are for implementation. I do not like that theyare placed in class body.

    On Jul 29, 1:38 pm, Immortal Nephi <> wrote:
    > Each member function can have more than one specification such as
    > char, short, long, enum, etc.


    Of course, but do you actually have code that goes with these
    specifications? Because the linker error is saying that MSVC
    cannot find the code that goes with the function you declared.
    I suspect that GCC simply falls back to the template code for
    operator char(), but MS is hung up on it.

    In other words, try getting rid of this line in data.cpp

    template
    Data< unsigned char >::eek:perator unsigned char ();

    *OR* implement it

    template<>
    Data<unsigned char>::eek:perator unsigned char() {
    return x;
    }

    [Of course, that doesn't explain why the constructor and
    destructor are found... ]

    > I put 15 enum specifications in EACH
    > member functions on source code.


    I don't know what this means, but I also can't see how it
    is relevant. Except that, you know, it sounds like what
    you posted isn't actually the code you're having problems
    with.

    --Jonathan
    Jonathan Lee, Jul 29, 2010
    #4
  5. Re: Separate Template Definition I wrote class Data in header. The C++ Compiler compiled without errors. I decided to move all member functions into source code because they are for implementation. I do not like that they are placed in class bo

    Immortal Nephi <> writes:

    > I wrote class Data in header. The C++ Compiler compiled without
    > errors. I decided to move all member functions into source code
    > because they are for implementation. I do not like that they are
    > placed in class body.
    >
    > I got error message:
    >
    > Linking...
    > Main.obj : error LNK2001: unresolved external symbol "public:
    > __thiscall Data<unsigned char>::eek:perator unsigned char(void)" (??B?
    > $Data@E@@QAEEXZ)
    > C:\Main.exe : fatal error LNK1120: 1 unresolved externals
    >
    > Could be problem with member function cast operator. All other
    > member functions complied without any problems.
    >
    > // Data.h
    > #if !defined(DATA_H )
    > #define DATA_H
    >
    > template< typename T >
    > class Data {
    > public:
    > Data();
    > ~Data();
    >
    > operator unsigned char ();
    >
    > private:
    > unsigned char x;
    > };
    >
    > #endif // end macro !defined( DATA_H )
    >
    >
    >
    > // Data.cpp
    >
    > template< typename T >
    > Data< T >::Data() : x( 5 ) {}
    >
    > template
    > Data< unsigned char >::Data();
    >
    >
    > template< typename T >
    > Data< T >::~Data() {}
    >
    > template
    > Data< unsigned char >::~Data();
    >
    >
    > // Error unresolved linkage
    > template< typename T >
    > Data< T >::eek:perator unsigned char () {
    > return x;
    > }
    >
    > template
    > Data< unsigned char >::eek:perator unsigned char ();
    >
    >
    >
    > // main.cpp
    >
    > int main() {
    > Data< unsigned char> data;
    > unsigned char x = data;
    >
    > return 0;
    > }


    Taking your code as is (adding only the relevant includes to Main.cpp
    and Data.cpp), I can confirm the link failure with VC++ 2008 Express:

    d:\CPPProjects\CLCPP>cl /EHsc Main.cpp Data.cpp
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01
    for 80x86
    Copyright (C) Microsoft Corporation. All rights reserved.

    Main.cpp
    Data.cpp
    Generating Code...
    Microsoft (R) Incremental Linker Version 9.00.30729.01
    Copyright (C) Microsoft Corporation. All rights reserved.

    /out:Main.exe
    Main.obj
    Data.obj
    Main.obj : error LNK2019: unresolved external symbol "public:
    __thiscall Data<unsigned char>::eek:perator unsigned char(void)"
    (??B?$Data@E@@QAEEXZ) referenced in function _main
    Main.exe : fatal error LNK1120: 1 unresolved externals

    d:\CPPProjects\CLCPP>

    However, the same code seems to compile fine using gcc-4.4.3:

    18:48:03 Paul Bibbings@JIJOU
    /cygdrive/d/CPPProjects/CLCPP $i686-pc-cygwin-g++-4.4.3 -static
    Main.cpp Data.cpp

    18:48:49 Paul Bibbings@JIJOU
    /cygdrive/d/CPPProjects/CLCPP $

    so, there appears to be some difference of opinion between the two
    compilers as to whether your code should work or not.

    Regards

    Paul Bibbings
    Paul Bibbings, Jul 29, 2010
    #5
  6. Re: Separate Template Definition I wrote class Data in header. The C++ Compiler compiled without errors. I decided to move all member functions into source code because they are for implementation. I do not like that they are placed in class body.

    Jonathan Lee <> writes:

    > On Jul 29, 12:39 pm, Immortal Nephi <>
    > wrote:
    >>         I wrote class Data in header.  The C++ Compiler compiled without
    >> errors.  I decided to move all member functions into source code
    >> because they are for implementation.  I do not like that they are
    >> placed in class body.
    >>
    >>         I got error message:
    >>
    >> Linking...
    >> Main.obj : error LNK2001: unresolved external symbol "public:
    >> __thiscall Data<unsigned char>::eek:perator unsigned char(void)" (??B?
    >> $Data@E@@QAEEXZ)
    >> C:\Main.exe : fatal error LNK1120: 1 unresolved externals
    >>
    >>         Could be problem with member function cast operator.  All other
    >> member functions complied without any problems.

    >
    > GCC compiled this without a complaint, so it's legal-ish (?).
    > BUT you have 3 specializations declared in data.cpp without
    > definitions. Maybe MS is expecting the definitions.
    >
    > (I actually have no idea if this is legal or not since I've
    > never declared a specialization and not immediately implemented
    > it).


    Is this right, what you are proposing here? If you look back at the OP's
    code, what he provided were not specializations at all, but rather
    *explicit instantiations*, including:

    template< typename T > // primary template
    Data< T >::eek:perator unsigned char() {
    return x;
    }

    template // explicit inst. for uchar
    Data< unsigned char >::eek:perator unsigned char();

    I'm not that up to speed on this because I have never found myself using
    explicit instantiations. Still, it is not my /expectation/ that any
    further `implementation' is required here. The OP's code is, surely,
    merely saying "I have this template. I shall be needing to use it on
    Data< unsigned char>. Instantiate the relevant member functions (ctor,
    dtor, op uchar) for me." Of course, this is necessary here, owing to the
    fact that the primary definitions are themselves present in a source,
    rather than a header, file. Beyond that, I'm not immediately seeing
    that there is any problem with this.

    Regards

    Paul Bibbings
    Paul Bibbings, Jul 29, 2010
    #6
  7. Re: Separate Template Definition I wrote class Data in header. TheC++ Compiler compiled without errors. I decided to move all member functionsinto source code because they are for implementation. I do not like that theyare placed in class body.

    On Jul 29, 1:06 pm, Paul Bibbings <> wrote:
    > Jonathan Lee <> writes:
    > > On Jul 29, 12:39 pm, Immortal Nephi <>
    > > wrote:
    > >>         I wrote class Data in header.  The C++ Compiler compiled without
    > >> errors.  I decided to move all member functions into source code
    > >> because they are for implementation.  I do not like that they are
    > >> placed in class body.

    >
    > >>         I got error message:

    >
    > >> Linking...
    > >> Main.obj : error LNK2001: unresolved external symbol "public:
    > >> __thiscall Data<unsigned char>::eek:perator unsigned char(void)" (??B?
    > >> $Data@E@@QAEEXZ)
    > >> C:\Main.exe : fatal error LNK1120: 1 unresolved externals

    >
    > >>         Could be problem with member function cast operator.  All other
    > >> member functions complied without any problems.

    >
    > > GCC compiled this without a complaint, so it's legal-ish (?).
    > > BUT you have 3 specializations declared in data.cpp without
    > > definitions. Maybe MS is expecting the definitions.

    >
    > > (I actually have no idea if this is legal or not since I've
    > > never declared a specialization and not immediately implemented
    > > it).

    >
    > Is this right, what you are proposing here?  If you look back at the OP's
    > code, what he provided were not specializations at all, but rather
    > *explicit instantiations*, including:
    >
    >    template< typename T >               // primary template
    >    Data< T >::eek:perator unsigned char() {
    >       return x;
    >    }
    >
    >    template                             // explicit inst. for uchar
    >    Data< unsigned char >::eek:perator unsigned char();
    >
    > I'm not that up to speed on this because I have never found myself using
    > explicit instantiations. Still, it is not my /expectation/ that any
    > further `implementation' is required here.  The OP's code is, surely,
    > merely saying "I have this template. I shall be needing to use it on
    > Data< unsigned char>. Instantiate the relevant member functions (ctor,
    > dtor, op uchar) for me."  Of course, this is necessary here, owing to the
    > fact that the primary definitions are themselves present in a source,
    > rather than a header, file.  Beyond that, I'm not immediately seeing
    > that there is any problem with this.


    Do Google and look for Q239436. It answers your question why Visual C+
    + 2008 fails to link template member function.
    Immortal Nephi, Jul 29, 2010
    #7
  8. Immortal Nephi

    Jonathan Lee Guest

    Re: Separate Template Definition I wrote class Data in header. TheC++ Compiler compiled without errors. I decided to move all member functionsinto source code because they are for implementation. I do not like that theyare placed in class body.

    On Jul 29, 2:06 pm, Paul Bibbings <> wrote:
    > Is this right, what you are proposing here?  If you look back at the OP's
    > code, what he provided were not specializations at all, but rather
    > *explicit instantiations*, including:


    Ahh.. that clears things up. I didn't realize you could do that
    per member function. I thought it was only for entire classes,
    as in

    template class Data<unsigned char>;

    In that case, ignore everything I said. You're absolutely right.

    --Jonathan
    Jonathan Lee, Jul 29, 2010
    #8
  9. Re: Separate Template Definition I wrote class Data in header. TheC++ Compiler compiled without errors. I decided to move all member functionsinto source code because they are for implementation. I do not like that theyare placed in class body.

    On Jul 29, 6:31 pm, Jonathan Lee <> wrote:
    > On Jul 29, 12:39 pm, Immortal Nephi <>
    > wrote:
    >
    > >         I wrote class Data in header.  The C++ Compiler compiled without
    > > errors.  I decided to move all member functions into source code
    > > because they are for implementation.  I do not like that they are
    > > placed in class body.

    >
    > >         I got error message:

    >
    > > Linking...
    > > Main.obj : error LNK2001: unresolved external symbol "public:
    > > __thiscall Data<unsigned char>::eek:perator unsigned char(void)" (??B?
    > > $Data@E@@QAEEXZ)
    > > C:\Main.exe : fatal error LNK1120: 1 unresolved externals

    >
    > >         Could be problem with member function cast operator.  All other
    > > member functions complied without any problems.

    >
    > GCC compiled this without a complaint, so it's legal-ish (?).
    > BUT you have 3 specializations declared in data.cpp without
    > definitions. Maybe MS is expecting the definitions.
    >
    > (I actually have no idea if this is legal or not since I've
    > never declared a specialization and not immediately implemented
    > it).
    >
    > --Jonathan




    Is this right, what you are proposing here? If you look back at the
    OP's
    code, what he provided were not specializations at all, but rather
    *explicit instantiations*, including:

    template< typename T > // primary template
    Data< T >::eek:perator unsigned char() {
    return x;
    }

    template // explicit inst. for uchar
    Data< unsigned char >::eek:perator unsigned char();

    I'm not that up to speed on this because I have never found myself
    using
    explicit instantiations. Still, it is not my /expectation/ that any
    further `implementation' is required here. The OP's code is, surely,
    merely saying "I have this template. I shall be needing to use it on
    Data< unsigned char>. Instantiate the relevant member functions (ctor,
    dtor, op uchar) for me." Of course, this is necessary here, owing to
    the
    fact that the primary definitions are themselves present in a source,
    rather than a header, file. Beyond that, I'm not immediately seeing
    that there is any problem with this.

    Regards

    Paul Bibbings
    Paul Bibbings, Jul 29, 2010
    #9
  10. Re: Separate Template Definition I wrote class Data in header. TheC++ Compiler compiled without errors. I decided to move all member functionsinto source code because they are for implementation. I do not like that theyare placed in class body.

    On Jul 29, 7:39 pm, Paul Bibbings <> wrote:

    Apologies for the double post on this.

    Regards

    Paul Bibbings
    Paul Bibbings, Jul 29, 2010
    #10
  11. Re: Separate Template Definition I wrote class Data in header. TheC++ Compiler compiled without errors. I decided to move all member functionsinto source code because they are for implementation. I do not like that theyare placed in class body.

    On Jul 29, 7:26 pm, Immortal Nephi <> wrote:
    > On Jul 29, 1:06 pm, Paul Bibbings <> wrote:
    >
    >
    >
    >
    >
    > > Jonathan Lee <> writes:
    > > > On Jul 29, 12:39 pm, Immortal Nephi <>
    > > > wrote:
    > > >>         I wrote class Data in header.  The C++ Compiler compiled without
    > > >> errors.  I decided to move all member functions into source code
    > > >> because they are for implementation.  I do not like that they are
    > > >> placed in class body.

    >
    > > >>         I got error message:

    >
    > > >> Linking...
    > > >> Main.obj : error LNK2001: unresolved external symbol "public:
    > > >> __thiscall Data<unsigned char>::eek:perator unsigned char(void)" (??B?
    > > >> $Data@E@@QAEEXZ)
    > > >> C:\Main.exe : fatal error LNK1120: 1 unresolved externals

    >
    > > >>         Could be problem with member function cast operator.  All other
    > > >> member functions complied without any problems.

    >
    > > > GCC compiled this without a complaint, so it's legal-ish (?).
    > > > BUT you have 3 specializations declared in data.cpp without
    > > > definitions. Maybe MS is expecting the definitions.

    >
    > > > (I actually have no idea if this is legal or not since I've
    > > > never declared a specialization and not immediately implemented
    > > > it).

    >
    > > Is this right, what you are proposing here?  If you look back at the OP's
    > > code, what he provided were not specializations at all, but rather
    > > *explicit instantiations*, including:

    >
    > >    template< typename T >               // primary template
    > >    Data< T >::eek:perator unsigned char() {
    > >       return x;
    > >    }

    >
    > >    template                             // explicit inst. for uchar
    > >    Data< unsigned char >::eek:perator unsigned char();

    >
    > > I'm not that up to speed on this because I have never found myself using
    > > explicit instantiations. Still, it is not my /expectation/ that any
    > > further `implementation' is required here.  The OP's code is, surely,
    > > merely saying "I have this template. I shall be needing to use it on
    > > Data< unsigned char>. Instantiate the relevant member functions (ctor,
    > > dtor, op uchar) for me."  Of course, this is necessary here, owing to the
    > > fact that the primary definitions are themselves present in a source,
    > > rather than a header, file.  Beyond that, I'm not immediately seeing
    > > that there is any problem with this.

    >
    > Do Google and look for Q239436.  It answers your question why Visual C+
    > + 2008 fails to link template member function.


    I think that there is a problem with VC over this. If you compile
    only your
    single file Data.cpp and then run objdump -t Data.obj, you will see
    that
    there is no symbol for the explicitly instantiated conversion operator
    in
    the table. On the other hand, even though we already have the
    evidence
    that it has no problem with explicit instantiations for the ctor and
    dtor,
    add a member function:

    // Data.h
    template< typename T >
    class Data {
    public:
    // ...
    unsigned char get() const;
    };

    // Data.cpp
    template< typename T >
    unsigned char Data<T>::get() const {
    return x;
    }

    template
    unsigned char Data< unsigned char >::get() const;

    then compile to Data.obj again. Run objdump -t Data.obj *now and
    you'll
    see that Data< unsigned char >::get() is in the symbol table.

    From this, it seems that VS is just not happy with honouring your
    request
    for an explicit instantiation of your op uchar. That's all that I
    can
    suggest.

    Regards

    Paul Bibbings
    Paul Bibbings, Jul 29, 2010
    #11
  12. Re: Separate Template Definition I wrote class Data in header. TheC++ Compiler compiled without errors. I decided to move all member functionsinto source code because they are for implementation. I do not like that theyare placed in class body.

    On Jul 29, 2:13 pm, Paul Bibbings <> wrote:
    > On Jul 29, 7:26 pm, Immortal Nephi <> wrote:
    >
    >
    >
    >
    >
    > > On Jul 29, 1:06 pm, Paul Bibbings <> wrote:

    >
    > > > Jonathan Lee <> writes:
    > > > > On Jul 29, 12:39 pm, Immortal Nephi <>
    > > > > wrote:
    > > > >>         I wrote class Data in header.  The C++ Compiler compiled without
    > > > >> errors.  I decided to move all member functions into source code
    > > > >> because they are for implementation.  I do not like that they are
    > > > >> placed in class body.

    >
    > > > >>         I got error message:

    >
    > > > >> Linking...
    > > > >> Main.obj : error LNK2001: unresolved external symbol "public:
    > > > >> __thiscall Data<unsigned char>::eek:perator unsigned char(void)" (??B?
    > > > >> $Data@E@@QAEEXZ)
    > > > >> C:\Main.exe : fatal error LNK1120: 1 unresolved externals

    >
    > > > >>         Could be problem with member function cast operator.  All other
    > > > >> member functions complied without any problems.

    >
    > > > > GCC compiled this without a complaint, so it's legal-ish (?).
    > > > > BUT you have 3 specializations declared in data.cpp without
    > > > > definitions. Maybe MS is expecting the definitions.

    >
    > > > > (I actually have no idea if this is legal or not since I've
    > > > > never declared a specialization and not immediately implemented
    > > > > it).

    >
    > > > Is this right, what you are proposing here?  If you look back at the OP's
    > > > code, what he provided were not specializations at all, but rather
    > > > *explicit instantiations*, including:

    >
    > > >    template< typename T >               // primary template
    > > >    Data< T >::eek:perator unsigned char() {
    > > >       return x;
    > > >    }

    >
    > > >    template                             // explicit inst. for uchar
    > > >    Data< unsigned char >::eek:perator unsigned char();

    >
    > > > I'm not that up to speed on this because I have never found myself using
    > > > explicit instantiations. Still, it is not my /expectation/ that any
    > > > further `implementation' is required here.  The OP's code is, surely,
    > > > merely saying "I have this template. I shall be needing to use it on
    > > > Data< unsigned char>. Instantiate the relevant member functions (ctor,
    > > > dtor, op uchar) for me."  Of course, this is necessary here, owing to the
    > > > fact that the primary definitions are themselves present in a source,
    > > > rather than a header, file.  Beyond that, I'm not immediately seeing
    > > > that there is any problem with this.

    >
    > > Do Google and look for Q239436.  It answers your question why Visual C+
    > > + 2008 fails to link template member function.

    >
    > I think that there is a problem with VC over this.  If you compile
    > only your
    > single file Data.cpp and then run objdump -t Data.obj, you will see
    > that
    > there is no symbol for the explicitly instantiated conversion operator
    > in
    > the table.  On the other hand, even though we already have the
    > evidence
    > that it has no problem with explicit instantiations for the ctor and
    > dtor,
    > add a member function:
    >
    >    // Data.h
    >    template< typename T >
    >    class Data {
    >    public:
    >       // ...
    >       unsigned char get() const;
    >    };
    >


    You can add many member functions in source code you like.

    >    // Data.cpp
    >    template< typename T >
    >    unsigned char Data<T>::get() const {
    >       return x;
    >    }



    Don't add that line below.

    >    template
    >    unsigned char Data< unsigned char >::get() const;


    I successfully resolved linkage failure. I fixed template class
    specification in source code. Cast operator function is working
    perfectly.

    Add line below.

    template
    class Data< unsigned char >;

    ...Before...add many member functions.

    Review my code again.

    // Data.h
    #if !defined(DATA_H )
    #define DATA_H


    template< typename T >
    class Data {
    public:
    Data();
    ~Data();

    operator unsigned char ();

    private:
    unsigned char x;
    };


    #endif // end macro !defined( DATA_H )

    // Data.cpp

    class Data< unsigned char >;

    template< typename T >
    Data< T >::Data() : x( 5 ) {}

    template< typename T >
    Data< T >::~Data() {}

    template< typename T >
    Data< T >::eek:perator unsigned char () {
    return x;
    }


    // main.cpp

    int main() {
    Data< unsigned char> data;
    unsigned char x = data;

    return 0;
    }

    MS Visual C++ Compiler compiled successfully without errors.
    Immortal Nephi, Jul 29, 2010
    #12
  13. Re: Separate Template Definition I wrote class Data in header. TheC++ Compiler compiled without errors. I decided to move all member functionsinto source code because they are for implementation. I do not like that theyare placed in class body.

    On Jul 29, 8:50 pm, Immortal Nephi <> wrote:
    > On Jul 29, 2:13 pm, Paul Bibbings <> wrote:
    >
    >
    >
    >
    >
    > > On Jul 29, 7:26 pm, Immortal Nephi <> wrote:

    >
    > > > On Jul 29, 1:06 pm, Paul Bibbings <> wrote:

    >
    > > > > Jonathan Lee <> writes:
    > > > > > On Jul 29, 12:39 pm, Immortal Nephi <>
    > > > > > wrote:
    > > > > >>         I wrote class Data in header.  The C++ Compiler compiled without
    > > > > >> errors.  I decided to move all member functions into source code
    > > > > >> because they are for implementation.  I do not like that they are
    > > > > >> placed in class body.

    >
    > > > > >>         I got error message:

    >
    > > > > >> Linking...
    > > > > >> Main.obj : error LNK2001: unresolved external symbol "public:
    > > > > >> __thiscall Data<unsigned char>::eek:perator unsigned char(void)" (??B?
    > > > > >> $Data@E@@QAEEXZ)
    > > > > >> C:\Main.exe : fatal error LNK1120: 1 unresolved externals

    >
    > > > > >>         Could be problem with member function cast operator.  All other
    > > > > >> member functions complied without any problems.

    >
    > > > > > GCC compiled this without a complaint, so it's legal-ish (?).
    > > > > > BUT you have 3 specializations declared in data.cpp without
    > > > > > definitions. Maybe MS is expecting the definitions.

    >
    > > > > > (I actually have no idea if this is legal or not since I've
    > > > > > never declared a specialization and not immediately implemented
    > > > > > it).

    >
    > > > > Is this right, what you are proposing here?  If you look back at the OP's
    > > > > code, what he provided were not specializations at all, but rather
    > > > > *explicit instantiations*, including:

    >
    > > > >    template< typename T >               // primary template
    > > > >    Data< T >::eek:perator unsigned char() {
    > > > >       return x;
    > > > >    }

    >
    > > > >    template                             // explicit inst. for uchar
    > > > >    Data< unsigned char >::eek:perator unsigned char();

    >
    > > > > I'm not that up to speed on this because I have never found myself using
    > > > > explicit instantiations. Still, it is not my /expectation/ that any
    > > > > further `implementation' is required here.  The OP's code is, surely,
    > > > > merely saying "I have this template. I shall be needing to use it on
    > > > > Data< unsigned char>. Instantiate the relevant member functions (ctor,
    > > > > dtor, op uchar) for me."  Of course, this is necessary here, owing to the
    > > > > fact that the primary definitions are themselves present in a source,
    > > > > rather than a header, file.  Beyond that, I'm not immediately seeing
    > > > > that there is any problem with this.

    >
    > > > Do Google and look for Q239436.  It answers your question why Visual C+
    > > > + 2008 fails to link template member function.

    >
    > > I think that there is a problem with VC over this.  If you compile
    > > only your
    > > single file Data.cpp and then run objdump -t Data.obj, you will see
    > > that
    > > there is no symbol for the explicitly instantiated conversion operator
    > > in
    > > the table.  On the other hand, even though we already have the
    > > evidence
    > > that it has no problem with explicit instantiations for the ctor and
    > > dtor,
    > > add a member function:

    >
    > >    // Data.h
    > >    template< typename T >
    > >    class Data {
    > >    public:
    > >       // ...
    > >       unsigned char get() const;
    > >    };

    >
    > You can add many member functions in source code you like.
    >
    > >    // Data.cpp
    > >    template< typename T >
    > >    unsigned char Data<T>::get() const {
    > >       return x;
    > >    }

    >
    > Don't add that line below.
    >
    > >    template
    > >    unsigned char Data< unsigned char >::get() const;

    >
    >         I successfully resolved linkage failure.  I fixed template class
    > specification in source code.  Cast operator function is working
    > perfectly.
    >
    >         Add line below.
    >
    > template
    > class Data< unsigned char >;
    >
    >         ...Before...add many member functions.
    >
    > Review my code again.
    >
    > // Data.h
    > #if !defined(DATA_H )
    > #define DATA_H
    >
    > template< typename T >
    > class Data {
    > public:
    >         Data();
    >         ~Data();
    >
    >         operator unsigned char ();
    >
    > private:
    >         unsigned char x;
    >
    > };
    >
    > #endif // end macro !defined( DATA_H )
    >
    > // Data.cpp
    >
    > class Data< unsigned char >;
    >
    > template< typename T >
    > Data< T >::Data() : x( 5 ) {}
    >
    > template< typename T >
    > Data< T >::~Data() {}
    >
    > template< typename T >
    > Data< T >::eek:perator unsigned char () {
    >         return x;
    >
    > }
    >
    > // main.cpp
    >
    > int main() {
    >         Data< unsigned char> data;
    >         unsigned char x = data;
    >
    >         return 0;
    >
    > }
    >
    >         MS Visual C++ Compiler compiled successfully without errors.


    I have tried this using VC++ 2008 (with cl /EHsc Main.cpp Data.cpp)
    and it
    doesn't work. I get, as I would expect:

    d:\CPPProjects\CLCPP>cl /EHsc Main.cpp Data.cpp
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version
    15.00.30729.01 for 80x86
    Copyright (C) Microsoft Corporation. All rights reserved.

    Main.cpp
    Data.cpp
    Data.cpp(5) : error C2906: 'Data<unsigned char>' : explicit
    specialization requires 'template <>'

    If I change the first code line of your Data.cpp to:

    template // explicit instantiation
    class Data< unsigned char >;

    then VC++ is apparently happy with it. (The omission of `template'
    may
    have been an oversight on your part when you posted your code.)

    However, I am not sure that this *should* work. To me, the explicit
    instantiation is then the wrong side of the template definitions, and
    certainly gcc-4.4.3 fails your code, thus corrected, with an undefined
    reference on *all* of the member functions of your Data class. If,
    then,
    you move the explicit instantiation to the *end* of your Data.cpp,
    after
    the definitions, then it works for both gcc and VC.

    However, this does not alter the fact that your first attempt -
    providing an explicit instantiation for each of the members
    individually -
    should have been accepted by VC also. In effect, all that you are
    doing
    here with your second attempt is doing in one line what you had
    previously
    requested be done in 3. I am beginning to think that there is a bug
    here
    in VC.

    Regards

    Paul Bibbings
    Paul Bibbings, Jul 30, 2010
    #13
    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. EvgueniB
    Replies:
    1
    Views:
    611
    Anthony Borla
    Dec 15, 2003
  2. Hans-Marc Olsen
    Replies:
    4
    Views:
    3,020
    Jacek Dziedzic
    Nov 19, 2004
  3. Gary li
    Replies:
    4
    Views:
    476
    Stuart Redmann
    Jun 29, 2006
  4. =?iso-8859-1?q?Erik_Wikstr=F6m?=
    Replies:
    5
    Views:
    2,298
    =?iso-8859-1?q?Erik_Wikstr=F6m?=
    Dec 14, 2006
  5. c
    Replies:
    43
    Views:
    1,507
    Richard
    Dec 15, 2007
Loading...

Share This Page