473,394 Members | 1,817 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.

problem with operator<<

Hey everyone!

So I'm writing my own String class to wrap std::string and implement an
API as close to identical as possible to the Java API. It's pretty
small so far:

#include <string>

class String
{
public:
String(std::string s) : mString(s)
{
}
String(const char* s) : mString(s)
{
}
String()
{
}
std::string& toStdString()
{
return mString;
}
const std::string& toStdString() const
{
return mString;
}
const char* toCString() const
{
return mString.c_str();
}
bool operator==(const String& s) const
{
return mString == s.mString;
}

private:
std::string mString;
};

Trying to use '<<' with a String results in the following predictable
result with g++:

error: no match for 'operator<<' in 'oss << s'

So, my String class became the following:

#include <ostream>
#include <string>

class String
{
public:
String(std::string s) : mString(s)
{
}
String(const char* s) : mString(s)
{
}
String()
{
}
std::string& toStdString()
{
return mString;
}
const std::string& toStdString() const
{
return mString;
}
const char* toCString() const
{
return mString.c_str();
}
bool operator==(const String& s) const
{
return mString == s.mString;
}

private:
std::string mString;

public:
friend std::ostream& operator<<(std::ostream& os, const String& s);
};

std::ostream& operator<<(std::ostream& os, const String& s)
{
os << s.mString;
return os;
}

But now I get the following very unpredictable result with g++:

multiple definition of `operator<<(std::basic_ostream<char,
std::char_traits<char> >&, String const&)'

I get this on line 40, which is the line 'std::ostream&
operator<<(std::ostream& os, const String& s)', the first line of the
definition.

Anyone have any ideas? Thanks ahead of time!

Jan 18 '06 #1
5 5645
Karl wrote:
Hey everyone!
[snip]
So, my String class became the following:

#include <ostream>
#include <string>

class String
{
public:
String(std::string s) : mString(s)
{
}
String(const char* s) : mString(s)
{
}
String()
{
}
std::string& toStdString()
{
return mString;
}
const std::string& toStdString() const
{
return mString;
}
const char* toCString() const
{
return mString.c_str();
}
bool operator==(const String& s) const
{
return mString == s.mString;
}

private:
std::string mString;

public:
friend std::ostream& operator<<(std::ostream& os, const String& s);
};

std::ostream& operator<<(std::ostream& os, const String& s)
{
os << s.mString;
return os;
}

But now I get the following very unpredictable result with g++:

multiple definition of `operator<<(std::basic_ostream<char,
std::char_traits<char> >&, String const&)'

I get this on line 40, which is the line 'std::ostream&
operator<<(std::ostream& os, const String& s)', the first line of the
definition.

Anyone have any ideas?


I'm not sure what the problem is, but I do have a potential solution.
Delete the friend declaration from your class definition. Then change
your operator<< definition to the following:

std::ostream& operator<<(std::ostream& os, const String& s)
{
os << s.toStdString();
return os;
}

I'm guessing this will eliminate the multiple definition error, and
also conforms your code to useful adage, "Don't grant friendship unless
there is a good reason to do so." In your code, there is no good
reason to do so.

Best regards,

Tom

Jan 18 '06 #2

"Karl" <ka*****@rit.edu> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...
Hey everyone!

So I'm writing my own String class to wrap std::string and implement an
API as close to identical as possible to the Java API. It's pretty
small so far:

#include <string>

class String
{
public:
String(std::string s) : mString(s)
{
}
String(const char* s) : mString(s)
{
}
String()
{
}
std::string& toStdString()
{
return mString;
}
const std::string& toStdString() const
{
return mString;
}
const char* toCString() const
{
return mString.c_str();
}
bool operator==(const String& s) const
{
return mString == s.mString;
}

private:
std::string mString;
};

Trying to use '<<' with a String results in the following predictable
result with g++:

error: no match for 'operator<<' in 'oss << s'

So, my String class became the following:

#include <ostream>
#include <string>

class String
{
public:
String(std::string s) : mString(s)
{
}
String(const char* s) : mString(s)
{
}
String()
{
}
std::string& toStdString()
{
return mString;
}
const std::string& toStdString() const
{
return mString;
}
const char* toCString() const
{
return mString.c_str();
}
bool operator==(const String& s) const
{
return mString == s.mString;
}

private:
std::string mString;

public:
friend std::ostream& operator<<(std::ostream& os, const String& s);
};

std::ostream& operator<<(std::ostream& os, const String& s)
{
os << s.mString;
return os;
}

But now I get the following very unpredictable result with g++:

multiple definition of `operator<<(std::basic_ostream<char,
std::char_traits<char> >&, String const&)'

I get this on line 40, which is the line 'std::ostream&
operator<<(std::ostream& os, const String& s)', the first line of the
definition.

Anyone have any ideas? Thanks ahead of time!


Is the above a header which you #include in more than one
source file? If so, that would be the cause of the error.
The defintion of the operator<< function should not be in a
header.

-Mike
Jan 18 '06 #3
Karl wrote:
Hey everyone!

So I'm writing my own String class to wrap std::string and implement an
API as close to identical as possible to the Java API. It's pretty
small so far:

#include <string>

class String
{ ... };

Trying to use '<<' with a String results in the following predictable
result with g++:

error: no match for 'operator<<' in 'oss << s'

So, my String class became the following:

#include <ostream>
#include <string>

class String
{ ... friend std::ostream& operator<<(std::ostream& os, const String& s);
};

std::ostream& operator<<(std::ostream& os, const String& s)
{
os << s.mString;
return os;
}

But now I get the following very unpredictable result with g++:

multiple definition of `operator<<(std::basic_ostream<char,
std::char_traits<char> >&, String const&)'

I get this on line 40, which is the line 'std::ostream&
operator<<(std::ostream& os, const String& s)', the first line of the
definition.

Anyone have any ideas? Thanks ahead of time!


If you choose to define operator<< in a header then you need to declare
it inline (or move it to a file which is only processed once by the
compiler-- generally a .cpp file). Otherwise the linker will see the
function declared multiple times in different translation units and emit
the error you observed.

You should also be using include guards in your header files:

#ifndef MY_STRING_H
#define MY_STRING_H

[body of header goes here]

#endif
Jan 18 '06 #4

Mark P wrote:
If you choose to define operator<< in a header then you need to declare
it inline (or move it to a file which is only processed once by the
compiler-- generally a .cpp file). Otherwise the linker will see the
function declared multiple times in different translation units and emit
the error you observed.

You should also be using include guards in your header files:

#ifndef MY_STRING_H
#define MY_STRING_H

[body of header goes here]

#endif


To the OP - Mike W and Mark P raise a valid point (and probably the
correct explanation of your problem) - if your definition of operator<<
appears in a header file, you need to either move it out of the header
file (but leave a declaration), or else define it as inline. But I
would still recommend you get rid of the friend declaration in the
class, since it isn't needed here.

Best regards,

Tom

Jan 18 '06 #5
Thanks everyone! I had this weird macro-header setup going, which
confused me entirely so I decided to scrap it. Everything's fine now.
Thanks!

Jan 19 '06 #6

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

Similar topics

4
by: franky.backeljauw | last post by:
Hello, I have a problem with using a copy constructor to convert an object of a templated class to object of another templated class. Let me first include the code (my question is below): ...
1
by: Piotre Ugrumov | last post by:
I'm following your help. I have written the overload of the operator <<. This overload work! :-) But I have some problem with the overload of the operator >>. I have written the overload of this...
3
by: Piotre Ugrumov | last post by:
I have done the overload on the operator >> and << in the class Attore. These 2 overload work correctly. I have done the overload of the same overload in the class Film. The class film ha inside...
3
by: Robert Wierschke | last post by:
Hi I want to overload the operator<< for a class Vector. class Vector { double x; double y; double z;
3
by: Alicia | last post by:
Hello, I am trying to figure out how to call an overloaded operator<< inherited from a base class. #ifndef PHONECALL #define PHONECALL #include "time.h" #include "interval.h"
3
by: Alex Vinokur | last post by:
Member operators operator>>() and operator<<() in a program below work fine, but look strange. Is it possible to define member operators operator>>() and operator<<() that work fine and look...
12
by: Filipe Sousa | last post by:
Hi! Could someone explain to me why this operation is not what I was expecting? int main() { int x = 2; std::cout << x << " " << x++ << std::endl; return 0; }
2
by: soy.hohe | last post by:
Hi all I have a class StreamLogger which implements operator << in this way: template <class TStreamLogger& operator<<(const T& t) { <print the stuff using fstream, etc.> return *this; }
1
by: Stuart Golodetz | last post by:
Hi guys, I'm trying to making an instance of a templated operator<< for a templated class a friend of that class (see below), to allow it to access the class internals for output purposes. ...
42
by: barcaroller | last post by:
In the boost::program_options tutorial, the author included the following code: cout << "Input files are: " << vm.as< vector<string() << "\n"; Basically, he is trying to print a vector...
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...
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...

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.