Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Separate Template Definition I wrote class Data in header. The C++Compiler compiled without errors. I decided to move all member functionsinto source code because they are for implementation. I do not like thatthey are placed in class body.

Reply
Thread Tools

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

 
 
Paul Bibbings
Guest
Posts: n/a
 
      07-29-2010
On Jul 29, 7:26*pm, Immortal Nephi <(E-Mail Removed)> wrote:
> On Jul 29, 1:06*pm, Paul Bibbings <(E-Mail Removed)> wrote:
>
>
>
>
>
> > Jonathan Lee <(E-Mail Removed)> writes:
> > > On Jul 29, 12:39*pm, Immortal Nephi <(E-Mail Removed)>
> > > 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>: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 >:perator unsigned char() {
> > * * * return x;
> > * *}

>
> > * *template * * * * * * * * * * * * * * // explicit inst. for uchar
> > * *Data< unsigned char >: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
 
Reply With Quote
 
 
 
 
Immortal Nephi
Guest
Posts: n/a
 
      07-29-2010
On Jul 29, 2:13*pm, Paul Bibbings <(E-Mail Removed)> wrote:
> On Jul 29, 7:26*pm, Immortal Nephi <(E-Mail Removed)> wrote:
>
>
>
>
>
> > On Jul 29, 1:06*pm, Paul Bibbings <(E-Mail Removed)> wrote:

>
> > > Jonathan Lee <(E-Mail Removed)> writes:
> > > > On Jul 29, 12:39*pm, Immortal Nephi <(E-Mail Removed)>
> > > > 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>: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 >:perator unsigned char() {
> > > * * * return x;
> > > * *}

>
> > > * *template * * * * * * * * * * * * * * // explicit inst. for uchar
> > > * *Data< unsigned char >: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 >:ata() : x( 5 ) {}

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

template< typename T >
Data< T >: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.
 
Reply With Quote
 
 
 
 
Paul Bibbings
Guest
Posts: n/a
 
      07-30-2010
On Jul 29, 8:50*pm, Immortal Nephi <(E-Mail Removed)> wrote:
> On Jul 29, 2:13*pm, Paul Bibbings <(E-Mail Removed)> wrote:
>
>
>
>
>
> > On Jul 29, 7:26*pm, Immortal Nephi <(E-Mail Removed)> wrote:

>
> > > On Jul 29, 1:06*pm, Paul Bibbings <(E-Mail Removed)> wrote:

>
> > > > Jonathan Lee <(E-Mail Removed)> writes:
> > > > > On Jul 29, 12:39*pm, Immortal Nephi <(E-Mail Removed)>
> > > > > 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>: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 >:perator unsigned char() {
> > > > * * * return x;
> > > > * *}

>
> > > > * *template * * * * * * * * * * * * * * // explicit inst. for uchar
> > > > * *Data< unsigned char >: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 >:ata() : x( 5 ) {}
>
> template< typename T >
> Data< T >::~Data() {}
>
> template< typename T >
> Data< T >: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
 
Reply With Quote
 
 
 
Reply

Thread Tools

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

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


Similar Threads
Thread Thread Starter Forum Replies Last Post
Help me, a friend of mine wrote a program in C# and I wrote the sameprogram in C..His is faster than mine on the same machine...How Come ? c C Programming 43 12-15-2007 01:01 PM
Template member functions in template class with separate definition =?iso-8859-1?q?Erik_Wikstr=F6m?= C++ 5 12-14-2006 01:04 PM
parse error in gcc but success in vc.net, call a non_template class's template member function from a template class's member function! ken C++ 2 06-28-2005 06:57 AM
g++ compiled C++ code called from gcc compiled C code Klaus Schneider C++ 1 12-02-2004 01:44 PM
Anyone know if they've decided on which codec to use for HD-DVD format? Jason DVD Video 6 09-16-2003 09:01 PM



Advertisments