Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > template implementation not seen by the compiler

Reply
Thread Tools

template implementation not seen by the compiler

 
 
Christof Warlich
Guest
Posts: n/a
 
      08-13-2006
Hi,

consider this:

template<typename T> class X {
public:
void doSomething(T t);
};
int main(void) {
X<int> x;
x.doSomething(4);
return 0;
}

It compiles fine but the linker is missing the implementation of
doSomething().

Why may it ever make sense that the compilation of this works fine? The
compiler already _knows_ that it could not instantiate doSomething() for
type int since it has not seen the (template) implementation of
doSomething(). Thus, linking will _always_ fail. Or do I miss a way to
pass the doSomething() implementation for a specific type to the linker
from another object file?

Thanks for any help,

Christof
 
Reply With Quote
 
 
 
 
Rolf Magnus
Guest
Posts: n/a
 
      08-13-2006
Christof Warlich wrote:

> Hi,
>
> consider this:
>
> template<typename T> class X {
> public:
> void doSomething(T t);
> };
> int main(void) {
> X<int> x;
> x.doSomething(4);
> return 0;
> }
>
> It compiles fine but the linker is missing the implementation of
> doSomething().
>
> Why may it ever make sense that the compilation of this works fine? The
> compiler already _knows_ that it could not instantiate doSomething() for
> type int since it has not seen the (template) implementation of
> doSomething().


It might not need to.

> Thus, linking will _always_ fail.


No. There could be another translation unit that defines doSomething() and
also instantiates the template for int. Then there would be an
implementation, but only the linker could find it.

 
Reply With Quote
 
 
 
 
Christof Warlich
Guest
Posts: n/a
 
      08-13-2006
Rolf Magnus wrote:

> No. There could be another translation unit that defines doSomething() and
> also instantiates the template for int. Then there would be an
> implementation, but only the linker could find it.


I was hoping to get exactly this answer as it makes sense and could
solve my design issue (see my post "virtual constructor ideom with
templates" above). But it unfortunately did not work: I tried the
following code, trying to translate it with

$ g++ -c main.cc
$ g++ -c implementation.cc
$ g++ main.o implementation.o -o main

but I still get the same error message from the linker. Any idea how
this can be made work?

Thanks,

Christof

// template.h
template<typename T> class X {
public:
void doSomething(T t);
};
// template.h ends

// main.cc
#include "template.h"
int main(void) {
X<int> x;
x.doSomething(4);
return 0;
}
// main.cc ends

// implementation.cc
#include "template.h"
template<typename T> void X<T>::doSomething(T t) {
// do something useful
}
X<int> dummy;
// implementation.cc ends


 
Reply With Quote
 
Greg
Guest
Posts: n/a
 
      08-13-2006

Christof Warlich wrote:
> Rolf Magnus wrote:
>
> > No. There could be another translation unit that defines doSomething() and
> > also instantiates the template for int. Then there would be an
> > implementation, but only the linker could find it.

>
> I was hoping to get exactly this answer as it makes sense and could
> solve my design issue (see my post "virtual constructor ideom with
> templates" above). But it unfortunately did not work: I tried the
> following code, trying to translate it with
>
> $ g++ -c main.cc
> $ g++ -c implementation.cc
> $ g++ main.o implementation.o -o main
>
> but I still get the same error message from the linker. Any idea how
> this can be made work?
>
> Thanks,
>
> Christof
>
> // template.h
> template<typename T> class X {
> public:
> void doSomething(T t);
> };
> // template.h ends
>
> // main.cc
> #include "template.h"
> int main(void) {
> X<int> x;
> x.doSomething(4);
> return 0;
> }
> // main.cc ends
>
> // implementation.cc
> #include "template.h"
> template<typename T> void X<T>::doSomething(T t) {
> // do something useful
> }
> X<int> dummy;
> // implementation.cc ends


The definition of a template must be visible at the point it is needed
in a source file. In this case, the doSomething() method is needed in
main.cc, but its definition is not visible to main.cc. Instead
doSomething's definition is found in implementation.cc - a source file
which has no need for it.

In order to ensure that template definitions are available to the
source code files that need them, the easiest solution (at least in the
absence of template export support) is to place template definitions in
header files. Therefore moving doSomething()'s definition to, say,
template.h while having main.cc include template.h would be the most
straightforward way to fix this problem.

Greg

 
Reply With Quote
 
Alex Buell
Guest
Posts: n/a
 
      08-13-2006
On Sun, 13 Aug 2006 09:44:52 +0200, I waved a wand and this message
magically appears in front of Christof Warlich:

> It compiles fine but the linker is missing the implementation of
> doSomething().
>
> Why may it ever make sense that the compilation of this works fine?
> The compiler already _knows_ that it could not instantiate doSomething
> () for type int since it has not seen the (template) implementation
> of doSomething(). Thus, linking will _always_ fail. Or do I miss a
> way to pass the doSomething() implementation for a specific type to
> the linker from another object file?


The compiler doesn't have to flag an error as the definition might be
in another file.
--
http://www.munted.org.uk

Bien sur mes talons sont toxiques. N'avez vous pas vu ma boite?
 
Reply With Quote
 
Rolf Magnus
Guest
Posts: n/a
 
      08-13-2006
Christof Warlich wrote:

> Rolf Magnus wrote:
>
>> No. There could be another translation unit that defines doSomething()
>> and also instantiates the template for int. Then there would be an
>> implementation, but only the linker could find it.

>
> I was hoping to get exactly this answer as it makes sense and could
> solve my design issue (see my post "virtual constructor ideom with
> templates" above). But it unfortunately did not work: I tried the
> following code, trying to translate it with
>
> $ g++ -c main.cc
> $ g++ -c implementation.cc
> $ g++ main.o implementation.o -o main
>
> but I still get the same error message from the linker. Any idea how
> this can be made work?
>
> Thanks,
>
> Christof
>
> // template.h
> template<typename T> class X {
> public:
> void doSomething(T t);
> };
> // template.h ends
>
> // main.cc
> #include "template.h"
> int main(void) {
> X<int> x;
> x.doSomething(4);
> return 0;
> }
> // main.cc ends
>
> // implementation.cc
> #include "template.h"
> template<typename T> void X<T>::doSomething(T t) {
> // do something useful
> }
> X<int> dummy;
> // implementation.cc ends


That might be because doSomething() isn't called in implemetation.cc and so
it's never instantiated. Try to use explicit template instantiation instead
of a dummy variable:

template class X<int>;
 
Reply With Quote
 
Christof Warlich
Guest
Posts: n/a
 
      08-13-2006
Greg wrote:
> The definition of a template must be visible at the point it is needed
> in a source file. In this case, the doSomething() method is needed in
> main.cc, but its definition is not visible to main.cc.

But that's my point: If the definition _has_ to be visible in main.cc,
why does only the linker and not already the compiler flag an error?
> Instead
> doSomething's definition is found in implementation.cc - a source file
> which has no need for it.

It _has_ a need for it; this is why I put the line
X<int> dummy;
into the file.
>
> In order to ensure that template definitions are available to the
> source code files that need them, the easiest solution (at least in the
> absence of template export support) is to place template definitions in
> header files. Therefore moving doSomething()'s definition to, say,
> template.h while having main.cc include template.h would be the most
> straightforward way to fix this problem.

I know, but it would not solve my design goal to to keep the
implementation invisible to the user.
 
Reply With Quote
 
Christof Warlich
Guest
Posts: n/a
 
      08-13-2006
Alex Buell wrote:
> The compiler doesn't have to flag an error as the definition might be
> in another file.

That's what Rolf Magnus already suggested. But do you have an idea _how_
I could feed this information to the compiler from another file? This
would just solve the issue I'm currently concerned with.

Please look at my response to Rolf Magnus to see my (straight forward
but unsuccessful) attempt.

Thanks and regards,

Christof
 
Reply With Quote
 
Christof Warlich
Guest
Posts: n/a
 
      08-13-2006
> That might be because doSomething() isn't called in implemetation.cc and so
> it's never instantiated. Try to use explicit template instantiation instead
> of a dummy variable:
>
> template class X<int>;

Hey, that's doing the trick! You've probably saved me another sleepless
night, so thank's a lot for your help.

Regards,

Christof
 
Reply With Quote
 
Greg
Guest
Posts: n/a
 
      08-13-2006
Christof Warlich wrote:
> Greg wrote:
> > The definition of a template must be visible at the point it is needed
> > in a source file. In this case, the doSomething() method is needed in
> > main.cc, but its definition is not visible to main.cc.

> But that's my point: If the definition _has_ to be visible in main.cc,
> why does only the linker and not already the compiler flag an error?


A referenced template has to be visible in order to be instantiated -
and every referenced template must be instantiated in order for the
program to link.

Strictly speaking, a template class or function does not need to be
instantiated in the same translation unit that uses it - just as long
as the template is instantiated in at least one of the other
translation units that are linked together to produce the final
program.

But there are notable disadvantages if the template is not instantiated
in the source file the requires it. Consider:

* Added bookkeeping overhead
Instead of the compiler instantiating templates as they are needed, the
programmer has to assume the tedious responsibility of determining
which templates need to be instantiated and to maintain this list
during development.

* Potential code bloat
A programmer is likely to instantiate an entire class template for a
particular type instead of just the method or methods actually
referenced.

* Lost optimization opportunities
With the template definition not present at the point it is needed, the
compiler loses the ability to inline function calls or to perform any
other optimization with the template.at the translation unit level.

Greg

 
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
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. Immortal Nephi C++ 12 07-30-2010 11:54 AM
Like all great travelers, I have seen more than I remember andremember more than I have seen. shenrilaa@gmail.com Java 0 03-06-2008 08:11 AM
Like all great travelers, I have seen more than I remember andremember more than I have seen. shenrilaa@gmail.com C++ 0 03-05-2008 08:41 AM
Like all great travelers, I have seen more than I remember andremember more than I have seen. shenrilaa@gmail.com C Programming 0 03-05-2008 03:26 AM
hiding non template dependent implementation in a template class er C++ 1 10-16-2007 01:15 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57