473,406 Members | 2,352 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,406 software developers and data experts.

Help with template friend and ostream, I think I am close

I searched but couldn't find anything _quite_ like this. I have some
code I inherited that needs some work. Basically I have a template
that is instantiated in the c++ code and so only the headers are
distributed. That works great, the only problem is that I cant get
the friend ostream inserter operator to work correctly. Basically
it never is instantiated so it never shows up in the library. Here is
a (close to) minimum example demonstrating the problem. I want
to be able to do this without having all the code in the header since
I know what instances I will need. Thanks in advance -- I believe
I am close on this, but just can't quite get it.

// Foo.hh
using namespace::std;
#include <iostream>

template<int> class Foo;
template<int mp>
std::ostream & operator<< (std::ostream&, const Foo<mp> &);

template<int mp>
class Foo {
public:
char x[mp];
Foo();
friend std::ostream & operator<< <>(std::ostream&,const Foo<mp> &);
};

// end of Foo.hh

// Foo.cc

#include "Foo.hh"

template<int mp>
Foo<mp>::Foo()
{
int i;
for (i=0;i<mp;i++);
x[i] = i;
}

template<int mp>
std::ostream & operator<< (std::ostream&, const Foo<mp> &)
{
cout << "Nothing" << endl;
}

template class Foo<2>;

// end of Foo.cc
If I try to link this code when trying to use cout with an instance of
Foo<2>:

/tmp/test/Main.cc:8: undefined reference to `std::basic_ostream<char,
std::char_traits<char> >& operator<< <(int)2>(std::basic_ostream<char,
std::char_traits<char> >&, Foo<(int)2> const&)'

And to confirm an nm on the object file Foo.o gives me:

nm --demangle Foo.o
00000054 t global constructors keyed to _ZN3FooILi2EEC1EvFoo.ccAPePOb
00000000 t __static_initialization_and_destruction_0(int, int)
00000000 W Foo<2>::Foo()
00000000 W Foo<2>::Foo()
U std::ios_base::Init::Init()
U std::ios_base::Init::~Init()
00000000 b std::__ioinit
U __cxa_atexit
U __dso_handle
U __gxx_personality_v0
00000040 t __tcf_0

Jan 13 '06 #1
5 2001
The friend part is done correctly, the error is in here:

truce wrote:
. Basically I have a template
that is instantiated in the c++ code and so only the headers are
distributed.


Unless you and everyone you distribute to uses a compiler that can
"export" templates, you cannot do that.

And then you'd have to use the export keyword.

Jan 13 '06 #2
truce wrote:
I searched but couldn't find anything _quite_ like this. I have some
code I inherited that needs some work. Basically I have a template
that is instantiated in the c++ code and so only the headers are
distributed. That works great, the only problem is that I cant get
the friend ostream inserter operator to work correctly.
The friendship of the output operator is not related to your problem.
Basically
it never is instantiated so it never shows up in the library. Here is
a (close to) minimum example demonstrating the problem. I want
to be able to do this without having all the code in the header since
I know what instances I will need. Thanks in advance -- I believe
I am close on this, but just can't quite get it.

[snip]

If you are really sure you know all instantiations of Foo<>:
be sure to call all related functions in foo.cc.

Regards, Stephan

Jan 13 '06 #3

"Stephan Brönnimann" <br****@hotmail.com> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
truce wrote:
Basically
it never is instantiated so it never shows up in the library. Here is
a (close to) minimum example demonstrating the problem. I want
to be able to do this without having all the code in the header since
I know what instances I will need. Thanks in advance -- I believe
I am close on this, but just can't quite get it.

[snip]

If you are really sure you know all instantiations of Foo<>:
be sure to call all related functions in foo.cc.


This is the part that I dont understand. I dont know how to force
the operator function. I do know how to force the template though.

In foo.cc instantiate the objects for Foo of any type that I will ever use.
This makes g++ generate all of the code in the template for any
instances of Foo<2>. When compiled with the -fno-implicit-templates
flag, the code is not needed in the header file. So I can write another
piece of code, say main.cc such as this and link successfully even though
at the time of compilation, it does not generate the code. It is already
in Foo.o.

#include "Foo.hh"
int main(void) {
Foo<2> xyz;
....
}

But clearly, this usage doesn't force the friend function to get
instantiated that is why it does not link successfully. That is what I am
trying to force. In the same way that template class Foo<2> forces the
compiler to include all the code for the class, I want to force the friend
function to be compiled as well.

I did not get the other posters mention of the export keyword. But I
distribute the library, headers, Makefile, and the cross compiler as a
toolkit so I do know what they are using.
Jan 13 '06 #4

truce wrote:

This is the part that I dont understand. I dont know how to force
the operator function. I do know how to force the template though.

In foo.cc instantiate the objects for Foo of any type that I will ever use.
This makes g++ generate all of the code in the template for any
instances of Foo<2>. When compiled with the -fno-implicit-templates
flag, the code is not needed in the header file. So I can write another
piece of code, say main.cc such as this and link successfully even though
at the time of compilation, it does not generate the code. It is already
in Foo.o. [OT]
Really?
The option -fno-implicit-templates is specific to g++
as well as its effects (I don't read the man page your way).
Just for fun: compile foo.cc with g++-3.3 and g++4.0, compare the
output.

By this your problem gets compiler (and most probaly version) specific:
How do I explictly instantiate a function template?
[/OT]
#include "Foo.hh"
int main(void) {
Foo<2> xyz;
....
}

But clearly, this usage doesn't force the friend function to get
instantiated that is why it does not link successfully. That is what I am
trying to force. In the same way that template class Foo<2> forces the
compiler to include all the code for the class, I want to force the friend
function to be compiled as well.

I did not get the other posters mention of the export keyword. But I
distribute the library, headers, Makefile, and the cross compiler as a
toolkit so I do know what they are using.


Regards, Stephan

Jan 13 '06 #5

"Stephan Brönnimann" <br****@hotmail.com> wrote in message
news:11*********************@z14g2000cwz.googlegro ups.com...

[OT]
Really?
The option -fno-implicit-templates is specific to g++
as well as its effects (I don't read the man page your way).
Just for fun: compile foo.cc with g++-3.3 and g++4.0, compare the
output.


Tried your test. g++ 4.0.2, 3.3.5, and 3.4.4 all did
the *exact* same thing and worked correctly.
All three allowed me to compile the implementation
file and link against my main object.

Further, I figured out how to do it .... for the benefit of
those who run across the same opportunity and want to
distribute headers + a library using templates.

// At the bottom of Foo.cc
// create the code for the template
template class Foo<2>;
// create the code for the operator
template ostream& operator << (ostream&, const Foo<2>&);
Jan 14 '06 #6

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

Similar topics

2
by: Christophe Barbe | last post by:
I posted a few days ago about the same problem but was not very clear. So here is my second take at it. Basically with GCC 3.3.2, I can't compile the example from the C++ FAQ Lite available...
5
by: Yoon-Soo Lee | last post by:
I am using Visual C++ .NET 2003 and running into some linking error from the following template code. The error messages is error LNK2019: unresolved external symbol "class...
5
by: Trevor Lango | last post by:
What is the appropriate syntax for placing a friend function that includes as one of it's parameters a pointer to the class object itself within the template class? I have the following: ...
6
by: Adam Parkin | last post by:
Hello, all I'm having a problem with friend functions in a templatized Queue class I'm writing using linked lists. The problem is that I can't get the friend function to be able to access private...
4
by: Amadeus W. M. | last post by:
What is the difference between friend ostream & operator<<(ostream & OUT, const Foo & f){ // output f return OUT; } and template <class X>
8
by: mast2as | last post by:
Hi guys, I think from what I found on the net that the code is correct and there's no problem when I compile the files. The problems occurs when I link them. I have a friend function which outputs...
3
by: Hamilton Woods | last post by:
Diehards, I developed a template matrix class back around 1992 using Borland C++ 4.5 (ancestor of C++ Builder) and haven't touched it until a few days ago. I pulled it from the freezer and...
4
by: fdmfdmfdm | last post by:
I have the following code: #include <iostream> #include <cstdlib> #include <cassert> using namespace std; template <class T> class Stack{ public: enum{DefaultStack = 10, EmptyStack = -1};
3
by: laikon | last post by:
this question is about how to define friend functions for a class template. the following is an example. template <typename T> class Array { private: T* parr; int sz;
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
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...

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.