where to declare a friend operator >> (as well as >>)... in .h or.cpp file

P

puzzlecracker

Say we have this structure:

Struct Foo{
....
friend ostream& operator << (ostream& s, Foo & m);
.....
};

friend ostream& operator << (ostream& s, Foo & m){

//access and print
}


I had a multiple inclusion issue when I placed the definition of
operator << in .h file despite include guards. So, I eventually moved
it to Foo.cpp class.

What is the suggested design ?


Thanks
 
P

puzzlecracker

If you place a function definition in a header file use the word 'inline',
unless it's defined within a class definition.

Umm, why inline is necessary in my case?

I only defined once in only one .h file, which obviously has include
guards. However, I have many other files, in the same project, that
include this .h file.
 
P

puzzlecracker

* puzzlecracker:




The include guard only prevents multiple includes in each compilation unit.

When you have multiple compilation units you have one (effective) include in each.

Thus one definition in each.

And when you have multiple definitions you need 'inline'.

Argh, got it, I like this subtle
Except if it's a template.

What is the rule with template in regard to putting the template
function in .h file.

Another question: what is the best design for opereraton<< design?



ty
 
M

mqrk

What is the rule with template in regard to putting the template
function in .h file?
I think you have to put a template function in a .h file if you plan
to use it in multiple compilation units. I've never heard of a system
that could handle template instantiation at link-time, though I heard
that Microsoft handles inline functions at link-time now, so maybe
template functions too? On the other hand, such code wouldn't be
portable so you probably don't want to use the feature even if it does
exist.
Another question: what is the best design for opereraton<< design?

I don't know. Here's what I do:

Code:
class A
{
public:
virtual std::ostream& operator>>(std::ostream& o) const { return o <<
"A's data";}
};

std::ostream& operator<<( std::ostream& o, const A& a)
{
return a >>  o;
}
 
J

James Kanze

On Sep 7, 4:42 pm, puzzlecracker <[email protected]>
wrote:> What is the rule with template in regard to putting
the template
I think you have to put a template function in a .h file if
you plan to use it in multiple compilation units. I've never
heard of a system that could handle template instantiation at
link-time,

Sun CC. Comeau C++.

Probably most Unix compilers, for that matter, except g++.
Traditionally, templates were instantiated at link time, and
most Unix vendor compilers try to support this, for reasons of
backwards compatibility, if for nothing else.

What is special is that you *can* put template and inline
functions in a header file, without incuring an error.
though I heard that Microsoft handles inline functions at
link-time now, so maybe template functions too? On the other
hand, such code wouldn't be portable so you probably don't
want to use the feature even if it does exist.
I don't know. Here's what I do:
Code:
class A
{
public:
virtual std::ostream& operator>>(std::ostream& o) const { return o <<
"A's data";}
};[/QUOTE]
[QUOTE]
std::ostream& operator<<( std::ostream& o, const A& a)
{
return a >>  o;}[/QUOTE]
[QUOTE]

Help. That's really confusing. I usually provide a normal,
named member function print, and derive from a template class
using the Barton and Nackman trick to provide the operators, but
otherwise, there's no problem with using a friend, as long as
you define it in a normal source file, and not in the header.
 
J

James Kanze

On Sep 7, 4:42 pm, puzzlecracker <[email protected]>
wrote:> What is the rule with template in regard to putting
the template
I think you have to put a template function in a .h file if
you plan to use it in multiple compilation units. I've never
heard of a system that could handle template instantiation at
link-time,

Sun CC. Comeau C++.

Probably most Unix compilers, for that matter, except g++.
Traditionally, templates were instantiated at link time, and
most Unix vendor compilers try to support this, for reasons of
backwards compatibility, if for nothing else.

What is special is that you *can* put template and inline
functions in a header file, without incuring an error.
though I heard that Microsoft handles inline functions at
link-time now, so maybe template functions too? On the other
hand, such code wouldn't be portable so you probably don't
want to use the feature even if it does exist.
I don't know. Here's what I do:
Code:
class A
{
public:
virtual std::ostream& operator>>(std::ostream& o) const { return o <<
"A's data";}
};[/QUOTE]
[QUOTE]
std::ostream& operator<<( std::ostream& o, const A& a)
{
return a >>  o;}[/QUOTE]
[QUOTE]

Help. That's really confusing. I usually provide a normal,
named member function print, and derive from a template class
using the Barton and Nackman trick to provide the operators, but
otherwise, there's no problem with using a friend, as long as
you define it in a normal source file, and not in the header.
 
P

puzzlecracker

I usually provide a normal,
named member function print, and derive from a template class
using the Barton and Nackman trick to provide the operators, but


Please elaborate on this:the Barton and Nackman trick
 
P

puzzlecracker

I usually provide a normal,
named member function print, and derive from a template class
using the Barton and Nackman trick to provide the operators, but


Please elaborate on this:the Barton and Nackman trick
 
J

James Kanze

I usually provide a normal,
Please elaborate on this:the Barton and Nackman trick

It's pretty straight-forward, really. The base class contains
an inline definition of the operator---declared as friend,
because that's the only way you can provide an implementation
inline in a class for a non-member function. It's not really
something fundamentally necessary for operator<< and >>; it's
more useful for things like an operator+ (based on +=), etc.
Anyway, you define a base class template along the lines of:

template< typename T >
class Operators
{
friend T operator+( T const& lhs, T const& rhs )
{
T result( lhs ) ;
result += rhs ;
return result ;
}
// ...
friend std::eek:stream& operator<<(
std::eek:stream const& dest,
T const& obj )
{
obj.print( dest ) ;
return dest ;
}
// ...
} ;

Then, whenever you need the operators, just derive from the
class:

class Whatever : public Operators< Whatever >
{
public :
// ...
Whatever& operator+=( Whatever const& other ) ;
// ...
void print( std::eek:stream& dest ) const ;
// ...
} ;

I actually have several different template base classes for
this: ArithmeticOperators, MixedArithmeticOperators (with two
template parameters, for mixed type arithmetic),
STLIteratorOpertors (converts a "normal" iterator into STL), and
IOStreamOperators.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top