Consider:
#include <string>
#include <iostream>
using namespace std;
struct S
{
const char* ps_;
operator string();
};
int main()
{
S s;
cout << s;
}
operator<<(ostream&, const string&) is defined in the standard and
the conversion from S to string is, too. But compilers reject this code
since operator<<(ostream&, const S&) is not defined.
What's wrong with this code?
--
ES Kim 14 1690
* ES Kim: Consider:
#include <string> #include <iostream> using namespace std;
struct S { const char* ps_; operator string(); };
int main() { S s; cout << s; }
operator<<(ostream&, const string&) is defined in the standard and the conversion from S to string is, too.
The Holy Standard says nothing about your struct S.
But compilers reject this code
As they should.
since operator<<(ostream&, const S&) is not defined.
If you're sure that's the reason...
What's wrong with this code?
.... then why are you asking this?
Is this homework?
Anyway, even with the code corrected (always post code that is complete,
if possible) MSVC 7.1 rejects it. It has no problem with conversion
to 'char const*', however. I don't know why, but one slight difference is
that in the MSVC implementation of the standard library the operator<< for
strings must infer template arguments such as the allocator type for the
string; why that should matter just baffles me, since both operator
implementations must infer template arguments for the stream.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
* Alf P. Steinbach: * ES Kim: Consider:
#include <string> #include <iostream> using namespace std;
struct S { const char* ps_; operator string(); };
int main() { S s; cout << s; }
Anyway, even with the code corrected (always post code that is complete, if possible) MSVC 7.1 rejects it. It has no problem with conversion to 'char const*', however. I don't know why, but one slight difference is that in the MSVC implementation of the standard library the operator<< for strings must infer template arguments such as the allocator type for the string; why that should matter just baffles me, since both operator implementations must infer template arguments for the stream.
Adding the following to the mix (after class S, for example) works so it
seems to have to do with template argument deduction -- there is a rule
about just direct conversions being tried, but I don't recall exactly:
template<class Traits> inline
basic_ostream<char, Traits>& operator<<(
basic_ostream<char, Traits>& stream,
const basic_string<char>& s
)
{
return std::operator<<( stream, s );
}
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
"Alf P. Steinbach" <al***@start.no> wrote in message
news:41****************@news.individual.net...
... code snipped operator<<(ostream&, const string&) is defined in the standard and the conversion from S to string is, too. The Holy Standard says nothing about your struct S.
But compilers reject this code
As they should.
since operator<<(ostream&, const S&) is not defined.
If you're sure that's the reason...
What's wrong with this code?
... then why are you asking this?
Is this homework?
I wish it were. I'm too old to do such a thing. ;-) Anyway, even with the code corrected (always post code that is complete, if possible) MSVC 7.1 rejects it. It has no problem with conversion to 'char const*', however. I don't know why,
Neither do I, and that's why I asked the question.
Ok, let me clarify.
struct S
{
operator const char*();
};
S s;
cout << s;
If you define S like this, it's fine, and operator<<(ostream&, const char*)
is called. Why not with operator string()?
but one slight difference is that in the MSVC implementation of the standard library the operator<< for strings must infer template arguments such as the allocator type for the string; why that should matter just baffles me, since both operator implementations must infer template arguments for the stream.
The original code is rejected not just with MSVC but also with gcc and comeau.
So I think it's not just an implementation problem but language-related one.
--
ES Kim
"Alf P. Steinbach" <al***@start.no> wrote in message
news:41*****************@news.individual.net... * Alf P. Steinbach: * ES Kim:
... code snipped
Anyway, even with the code corrected (always post code that is complete, if possible) MSVC 7.1 rejects it. It has no problem with conversion to 'char const*', however. I don't know why, but one slight difference is that in the MSVC implementation of the standard library the operator<< for strings must infer template arguments such as the allocator type for the string; why that should matter just baffles me, since both operator implementations must infer template arguments for the stream.
Adding the following to the mix (after class S, for example) works so it seems to have to do with template argument deduction -- there is a rule about just direct conversions being tried, but I don't recall exactly:
template<class Traits> inline basic_ostream<char, Traits>& operator<<( basic_ostream<char, Traits>& stream, const basic_string<char>& s ) { return std::operator<<( stream, s ); }
Well, I don't think this is a solution. If this code and std::string-related
headers are included in a same source somehow, it will cause an ambiguity.
--
ES Kim
* ES Kim: template<class Traits> inline basic_ostream<char, Traits>& operator<<( basic_ostream<char, Traits>& stream, const basic_string<char>& s ) { return std::operator<<( stream, s ); }
Well, I don't think this is a solution. If this code and std::string-related headers are included in a same source somehow, it will cause an ambiguity.
Well it doesn't with MSVC 7.1. And I don't think with any other compiler
either. It's a better match -- but perhaps one should take a look at
what operator<<'s the standard specifies (I'm too lazy to do that).
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
"Alf P. Steinbach" <al***@start.no> wrote in message
news:41*****************@news.individual.net... * ES Kim: template<class Traits> inline basic_ostream<char, Traits>& operator<<( basic_ostream<char, Traits>& stream, const basic_string<char>& s ) { return std::operator<<( stream, s ); } Well, I don't think this is a solution. If this code and
std::string-related headers are included in a same source somehow, it will cause an ambiguity.
Well it doesn't with MSVC 7.1. And I don't think with any other compiler either.
Hmmm... that's strange. It does with gcc and comeau, not just with MSVC.
Here's my test code:
#include <iostream>
#include <string>
struct S
{
char* s;
operator string();
};
// your code
template<class Traits> inline
basic_ostream<char, Traits>& operator<<(
basic_ostream<char, Traits>& stream,
const basic_string<char>& s
)
{
return std::operator<<( stream, s );
}
int main()
{
S s;
std::cout << s;
std::string str;
std::cout << str; // ambiguous
}
It's a better match -- but perhaps one should take a look at what operator<<'s the standard specifies (I'm too lazy to do that).
This is from the standard:
template<class charT, class traits, class Allocator>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& os,
const basic_string<charT, traits, Allocator>& str);
Does your code match better than this one? I'm not sure.
--
ES Kim
* ES Kim: "Alf P. Steinbach" <al***@start.no> wrote in message news:41*****************@news.individual.net... * ES Kim: > > template<class Traits> inline > basic_ostream<char, Traits>& operator<<( > basic_ostream<char, Traits>& stream, > const basic_string<char>& s > ) > { > return std::operator<<( stream, s ); > }
Well, I don't think this is a solution. If this code and std::string-related headers are included in a same source somehow, it will cause an ambiguity.
Well it doesn't with MSVC 7.1. And I don't think with any other compiler either.
Hmmm... that's strange. It does with gcc and comeau, not just with MSVC. Here's my test code:
#include <iostream> #include <string>
struct S { char* s; operator string(); };
// your code template<class Traits> inline basic_ostream<char, Traits>& operator<<( basic_ostream<char, Traits>& stream, const basic_string<char>& s ) { return std::operator<<( stream, s ); }
int main() { S s; std::cout << s; std::string str; std::cout << str; // ambiguous }
Ooops. It's a better match -- but perhaps one should take a look at what operator<<'s the standard specifies (I'm too lazy to do that).
This is from the standard:
template<class charT, class traits, class Allocator> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str);
Does your code match better than this one? I'm not sure.
I'm not sure either.
In such situations I apply the simple rule: don't rely on things that
are hard to understand or generally unknown.
So a 'toString' member function in class S is one solution (although it
would be nice to know the answer(s) to this question, also).
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
"Alf P. Steinbach" <al***@start.no> wrote in message
news:41*****************@news.individual.net... So a 'toString' member function in class S is one solution (although it would be nice to know the answer(s) to this question, also).
Yes, this is what I would do in real code. Someone asked the question
and I was just curious. No, not exactly. I'm dying to know the answer. :-)
--
ES Kim
ES Kim wrote: Consider:
#include <string> #include <iostream> using namespace std;
struct S { const char* ps_; operator string(); };
int main() { S s; cout << s; }
operator<<(ostream&, const string&) is defined in the standard and the conversion from S to string is, too. But compilers reject this code since operator<<(ostream&, const S&) is not defined. What's wrong with this code?
The most serious error here is that you use operator definition for fun.
operator definitions can cause unexpected/hidden errors, so must be used
with extreme caution.
#include <string>
#include <iostream>
struct S
{
const char *ps_;
};
inline
std::ostream &operator<<(std::ostream &o, const S &s)
{
return std::cout<<s.ps_;
}
int main()
{
S s = {0};
std::cout << s;
}
--
Ioannis Vranos http://www23.brinkster.com/noicys
Ioannis Vranos wrote: The most serious error here is that you use operator definition for fun. operator definitions can cause unexpected/hidden errors, so must be used with extreme caution.
I was talking about operator Type() definitions. Avoid them.
--
Ioannis Vranos http://www23.brinkster.com/noicys
"Ioannis Vranos" <iv*@guesswh.at.grad.com> wrote in message
news:cj***********@ulysses.noc.ntua.gr... Ioannis Vranos wrote: The most serious error here is that you use operator definition for fun. operator definitions can cause unexpected/hidden errors, so must be used with extreme caution.
I was talking about operator Type() definitions. Avoid them.
Yes, I know why the conversion operator must be used with caution
and agree on that. But I'm not talking about the recommended style.
What I'm asking is "Why the original code is rejected even if the
conversion is defined?" It's about syntax.
--
ES Kim
ES Kim posted: Consider:
#include <string> #include <iostream> using namespace std;
struct S { const char* ps_; operator string(); };
int main() { S s; cout << s; }
operator<<(ostream&, const string&) is defined in the standard and the conversion from S to string is, too. But compilers reject this code since operator<<(ostream&, const S&) is not defined. What's wrong with this code?
int main()
{
k = 7;
}
That's one problem in anyway.
-JKop
"ES Kim" <no@spam.mail> wrote in message news:<cj**********@news1.kornet.net>... Consider:
#include <string> #include <iostream> using namespace std;
struct S { const char* ps_; operator string(); };
int main() { S s; cout << s; }
operator<<(ostream&, const string&) is defined in the standard and the conversion from S to string is, too. But compilers reject this code since operator<<(ostream&, const S&) is not defined. What's wrong with this code?
With the code:
cout << s;
Why would the compiler look for an << operator in std::string?
It can't go looking into every possible conversion type for obvious reasons.
Paul.
ES Kim wrote in news:cj**********@news1.kornet.net in comp.lang.c++: Consider:
#include <string> #include <iostream> using namespace std;
struct S { const char* ps_; operator string(); };
int main() { S s; cout << s; }
operator<<(ostream&, const string&) is defined in the standard and the conversion from S to string is, too. But compilers reject this code since operator<<(ostream&, const S&) is not defined. What's wrong with this code?
std::string is a typedef for std::basic_string< char > and operator <<
in std is a template and its second argument is involved in TAD (template
argument deduction), such template arguments must be exact matches.
The only (*) conversion's allowed (or possible if you like) are derived
to base conversion's, User defined convertion's (operator Type()
and converting constructors) aren't considered as they can play no
role in TAD.
*) All the normal rvalue/lvalue and qualification adjustment can
occur as usual.
An example:
#include <iostream>
#include <ostream>
/* Forward
*/
template < typename T > struct D;
template < typename T > struct A
{
A() {}
A( D< T > const & ) {};
};
template < typename T > struct B : A < T > {};
template < typename T > struct C
{
operator A< T > () const { return A< T >(); }
};
template < typename T > struct D {};
template < typename T >
void f( A< T > )
{
std::cout << "f( A< T > )\n";
}
int main()
{
A< int > a;
f( a );
B< int > b;
f( b );
#if 0
C< int > c;
f( c ); /* Not Ok User defined conversion (operator) */
#endif
#if 0
D< int > d;
f( d ); /* Not Ok User defined conversion (constructor) */
#endif
}
HTH.
Rob.
-- http://www.victim-prime.dsl.pipex.com/ This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Christophe Poucet |
last post by:
Hellom
I have an issue with implicit conversions. Apparently when one calls
an operator on a class Y which has a conversion operator to class X
which has the operator . Sadly it will not do...
|
by: Michael Lehn |
last post by:
Hi,
I have a question regarding the conversion of objects. When is the
conversion done by the constructor and when by the operator. My feeling
tells me that the constructor is preferred. But...
|
by: Arne Schmitz |
last post by:
I guess this has been asked before, but I cannot find any answer to this
problem. I have program like this:
---SNIP---
#include <cassert>
#include <cstdlib>
class C
{
public:
|
by: Steve Gough |
last post by:
Could anyone please help me to understand what is happening here? The
commented line produces an error, which is what I expected given that
there is no conversion defined from type double to type...
|
by: Steve Richter |
last post by:
here is a warning I am getting in a C++ .NET compile:
c:\SrNet\jury\JuryTest.cpp(55) : warning C4927: illegal conversion;
more than one user-defined conversion has been implicitly applied
while...
|
by: rawCoder |
last post by:
Hi,
Just wanted to know if there is any speed difference between
VB conversion Keywords like CInt, Clng, CStr, CDbl, CBool etc.
..NETs Convert.To<...> methods.
And which is better to be...
|
by: Jim Langston |
last post by:
I use a game engine using MSVC++ .net 2003 and have no problems. Some users
of DevC++ who use the same engine crash at times when a copy of this
structure is the return variable. I don't have...
|
by: Rahul |
last post by:
Hi Everyone,
I have the following code,
class B;
class A
{
public : operator B();
|
by: fabian.lim |
last post by:
Hi all,
Im having a problem with my code. Im programming a vector class,
and am trying to overload the () operator in 2 different situations.
The first situation is to assign values, e.g. Y =...
|
by: CloudSolutions |
last post by:
Introduction:
For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome former...
|
by: taylorcarr |
last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
|
by: aa123db |
last post by:
Variable and constants
Use var or let for variables and const fror constants.
Var foo ='bar';
Let foo ='bar';const baz ='bar';
Functions
function $name$ ($parameters$) {
}
...
|
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...
|
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...
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
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...
| |