MSVC operator problem

Started by
19 comments, last by rozz666 16 years, 8 months ago
Quote:Original post by dmatter
Take a look at the STL's std::string,

1) Use it

2) Instead of overloading the pointer operator it has a function c_str(), not only does this make it more explicit what's happening, which I feel in this case is a good-thing, but it avoids the ambiguity.


I can't use std::string, because I need some more functionality than it has. I know I could inherit from std::string, that wouldnt spare my much time implementing my string class. Moreover, I use expression templates for operator+, so I really have no benefit from using std::string.
Advertisement
edit: didn't read closely enough
Quote:Original post by rozz666
Do you see my point?
It's obvious that's Y::f. Why operator[] isn't working the same way?


I agree that it doesn't make sense—to me, <edit>implicit</edit> casting on the left-hand side of operator[] should be forbidden, as with all other binary operators which accept lvalues as their left members. Neither Visual C++ nor g++ manage to get this right, though—g++ is worse than VC in this regard, because it's not consistent: it acts as if casting was forbidden when it would create an ambiguity, and acts as if it was allowed otherwise.
Quote:Original post by ToohrVyk
Quote:Original post by rozz666
Do you see my point?
It's obvious that's Y::f. Why operator[] isn't working the same way?


I agree that it doesn't make sense—to me, <edit>implicit</edit> casting on the left-hand side of operator[] should be forbidden, as with all other binary operators which accept lvalues as their left members. Neither Visual C++ nor g++ manage to get this right, though—g++ is worse than VC in this regard, because it's not consistent: it acts as if casting was forbidden when it would create an ambiguity, and acts as if it was allowed otherwise.


So now, that we agree that it doesn't make sense, we need to find out what's the standard says about it. It means buying ANSI sheet or Comeau compiler, so I hope someone in this forum hopefully has one of these?
Quote:Original post by rozz666
So now, that we agree that it doesn't make sense, we need to find out what's the standard says about it. It means buying ANSI sheet or Comeau compiler, so I hope someone in this forum hopefully has one of these?


There's also the standard draft, which is freely available online.

In particular:

Quote:13.5.5 §1
operator[] shall be a non-static member function with exactly one
parameter. It implements the subscripting syntax
postfix-expression [ expression ]
Thus, a subscripting expression x[y] is interpreted as x.operator[](y)
for a class object x of type T if T::operator[](T1) exists and if the
operator is selected as the best match function by the overload reso-
lution mechanism (_over.match.best_).


And:

Quote:13.3.1.2
§4 For the built-in assignment operators, conversions of the left operand
are restricted as follows:

--no temporaries are introduced to hold the left operand, and

--no user-defined conversions are applied to the left operand to
achieve a type match with the left-most parameter of a built-in can-
didate.

§5 For all other operators, no such restrictions apply.


Hm. So, for every possible conversion, the compiler determines if an user-defined or built-in operator exists, and chooses the least ambiguous one, and the = operator is restricted.

I have to leave now, so I'll let the rest of the reading to you. [smile]
Quote:Original post by ToohrVyk
Quote:Original post by rozz666
So now, that we agree that it doesn't make sense, we need to find out what's the standard says about it. It means buying ANSI sheet or Comeau compiler, so I hope someone in this forum hopefully has one of these?


There's also the standard draft, which is freely available online.

In particular:

Quote:13.5.5 §1
operator[] shall be a non-static member function with exactly one
parameter. It implements the subscripting syntax
postfix-expression [ expression ]
Thus, a subscripting expression x[y] is interpreted as x.operator[](y)
for a class object x of type T if T::operator[](T1) exists and if the
operator is selected as the best match function by the overload reso-
lution mechanism (_over.match.best_).


And:

Quote:13.3.1.2
§4 For the built-in assignment operators, conversions of the left operand
are restricted as follows:

--no temporaries are introduced to hold the left operand, and

--no user-defined conversions are applied to the left operand to
achieve a type match with the left-most parameter of a built-in can-
didate.

§5 For all other operators, no such restrictions apply.


Hm. So, for every possible conversion, the compiler determines if an user-defined or built-in operator exists, and chooses the least ambiguous one, and the = operator is restricted.

I have to leave now, so I'll let the rest of the reading to you. [smile]



Thanks, I'll check it out.
g++ is right!

Quote: 13.3.3.2
§2 When comparing the basic forms of implicit conversion sequences (as
defined in _over.best.ics_)

--a standard conversion sequence (_over.ics.scs_) is a better conver-
sion sequence than a user-defined conversion sequence or an ellipsis
conversion sequence, and

--a user-defined conversion sequence (_over.ics.user_) is a better
conversion sequence than an ellipsis conversion sequence
(_over.ics.ellipsis_).


So, the X → int* conversion is strictly worse than unsigned → int, and there should be no ambiguity.

In the end, judging from our human difficulty to resolve the ambiguity, I'd say it's pretty dangerous to leave it this way.
Quote:Original post by rozz666
I can't use std::string, because I need some more functionality than it has.

Like what?
Quote:Original post by rozz666
I can't use std::string, because I need some more functionality than it has.


What kind of functionality?

Quote:I know I could inherit from std::string, that wouldnt spare my much time implementing my string class.


Have you tried? You might be surprised. (Also consider composition instead of inheritance.) If you have to get at a lower level (e.g. because of the next part...), at least consider if std::vector is useful for storage.

Quote:Moreover, I use expression templates for operator+, so I really have no benefit from using std::string.


To avoid multiple reallocation? Oh, that sounds like a pretty major project. x.x
Quote:Original post by rozz666
I can't use std::string, because I need some more functionality than it has. I know I could inherit from std::string, that wouldnt spare my much time implementing my string class. Moreover, I use expression templates for operator+, so I really have no benefit from using std::string.

If you need to extend a standard container then aggregate it or write some custom algorithms.
You can let std::string handle 90% of the string management for you. If you think about it with std::string all the memory handling and most of the funtionality is already there, you can use that and just build from there.

Example aggregation:
class MyString{public:    // Extra functionality.protected:    std::string _string;};

This topic is closed to new replies.

Advertisement