473,394 Members | 1,714 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

template implementation not seen by the compiler

Hi,

consider this:

template<typename Tclass X {
public:
void doSomething(T t);
};
int main(void) {
X<intx;
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
Aug 13 '06 #1
9 1802
Christof Warlich wrote:
Hi,

consider this:

template<typename Tclass X {
public:
void doSomething(T t);
};
int main(void) {
X<intx;
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.

Aug 13 '06 #2
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 Tclass X {
public:
void doSomething(T t);
};
// template.h ends

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

// implementation.cc
#include "template.h"
template<typename Tvoid X<T>::doSomething(T t) {
// do something useful
}
X<intdummy;
// implementation.cc ends
Aug 13 '06 #3

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 Tclass X {
public:
void doSomething(T t);
};
// template.h ends

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

// implementation.cc
#include "template.h"
template<typename Tvoid X<T>::doSomething(T t) {
// do something useful
}
X<intdummy;
// 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

Aug 13 '06 #4
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?
Aug 13 '06 #5
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 Tclass X {
public:
void doSomething(T t);
};
// template.h ends

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

// implementation.cc
#include "template.h"
template<typename Tvoid X<T>::doSomething(T t) {
// do something useful
}
X<intdummy;
// 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>;
Aug 13 '06 #6
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<intdummy;
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. :-(
Aug 13 '06 #7
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
Aug 13 '06 #8
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
Aug 13 '06 #9
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

Aug 13 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

31
by: nikola | last post by:
Hi all, I was working with a simple function template to find the min of two values. But since I would like the two values to be different (type) I dont know what kind of value (type) it will...
5
by: Nomak | last post by:
Hello all, i have two template classes which needs each other. I tried to write some fwd decl / decl / impl in a good way but i can't get it to compile. Explanations: - .hh files are for...
10
by: philchen1978 | last post by:
Hi, I can compile the code below with GCC 3.4.2, because function g is a "dependent name". template<class T> void f1(T t) { g(t); }
6
by: RainBow | last post by:
Greetings!! I introduced the so-called "thin-template" pattern for controlling the code bloat caused due to template usage. However, one of the functions in the template happens to be virtual...
3
by: Grahamo | last post by:
Hi, I have a question that pertains to Templates and link time. This is totally for my own understanding and to correct what's obviously an erroneous view of things on my behalf; Lets say I...
45
by: charles.lobo | last post by:
Hi, I have recently begun using templates in C++ and have found it to be quite useful. However, hearing stories of code bloat and assorted problems I decided to write a couple of small programs...
272
by: Peter Olcott | last post by:
http://groups.google.com/group/comp.lang.c++/msg/a9092f0f6c9bf13a I think that the operator() member function does not work correctly, does anyone else know how to make a template for making two...
0
by: anto.anish | last post by:
Hi , Since, i did not want to write all instantiations in Source file of all template methods for various different datatypes that my client might use, Instead, i choose to write implementation...
6
by: Gaijinco | last post by:
I'm trying to do a template class Node. My node.hpp is: #ifndef _NODE_HPP_ #define _NODE_HPP_ namespace com { namespace mnya { namespace carlos { template <typename T>
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.