How to subscript a CString? (CSimpleStringT::operator[])

N

Norman Diamond

In an antique obsolete version of MFC, a CString expression could be
subscripted in order to retrieve one element.

Visual Studio 2005 defines CSimpleStringT::blush:perator[]. At first glance it
looks like it might have been intended to provide backwards compatibility
for antique programs. But there seems to be no way to use it.

CString s = _T("ab");
short i = 1;
_TCHAR c = s;

Error C2666, ambiguous overload.

In atlsimpstr.h I find one whole uniguous overload of operator[]. In
cstringt.h I find none. Where is the other one, and is there any way to
overcome it?
 
T

Tom Serface

I don't know about the [] operator (I don't use it), but GetAt() still
works.

Tom
 
J

Jonathan Wood

That syntax has always worked for me. I'm not familiar with _TCHAR--I just
use TCHAR.

Not really sure where the ambiguity comes in. Are you building Unicode? Does
char c = s[1] work? Does TCHAR c = s[0] work ???
 
N

Norman Diamond

Thank you, I will use GetAt().

I wonder why Visual Studio 2005 includes a definition which looks like it's
intended for backwards compatibility but which Visual Studio 2005 prevents
from working.

Tom Serface said:
I don't know about the [] operator (I don't use it), but GetAt() still
works.

Tom

Norman Diamond said:
In an antique obsolete version of MFC, a CString expression could be
subscripted in order to retrieve one element.

Visual Studio 2005 defines CSimpleStringT::blush:perator[]. At first glance
it looks like it might have been intended to provide backwards
compatibility for antique programs. But there seems to be no way to use
it.

CString s = _T("ab");
short i = 1;
_TCHAR c = s;

Error C2666, ambiguous overload.

In atlsimpstr.h I find one whole uniguous overload of operator[]. In
cstringt.h I find none. Where is the other one, and is there any way to
overcome it?

 
N

Norman Diamond

There's no difference between Microsoft's definitions of _TCHAR and TCHAR.
From the point of view of hypothetical possible conformance to standards
some day, implementations are free to define identifiers like _TCHAR however
they like, but like TCHAR. Either way my program is obviously
implementation dependant.

This project is not a Unicode build. I didn't test to see if Visual Studio
might work with this if it were Unicode. But this is old code and there's
neither funding nor time to convert it from ANSI (code page 932) to Unicode.
Does char c = s[1] work?

I didn't try it, but: Wouldn't it be an even bigger WTF if
CSimpleStringT::blush:perator[] would disambiguate itself (wherever the ambiguity
is, which I haven't found) on account of something that's going to happen to
the resulting rvalue after it crosses to the other side of the assignment
operator to get stored?


Jonathan Wood said:
That syntax has always worked for me. I'm not familiar with _TCHAR--I just
use TCHAR.

Not really sure where the ambiguity comes in. Are you building Unicode?
Does char c = s[1] work? Does TCHAR c = s[0] work ???

--
Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com


Norman Diamond said:
In an antique obsolete version of MFC, a CString expression could be
subscripted in order to retrieve one element.

Visual Studio 2005 defines CSimpleStringT::blush:perator[]. At first glance
it looks like it might have been intended to provide backwards
compatibility for antique programs. But there seems to be no way to use
it.

CString s = _T("ab");
short i = 1;
_TCHAR c = s;

Error C2666, ambiguous overload.

In atlsimpstr.h I find one whole uniguous overload of operator[]. In
cstringt.h I find none. Where is the other one, and is there any way to
overcome it?

 
N

Norman Diamond

Does char c = s[1] work?

Oh I see, it works because this 1 is an int.

char c = s[(short)1] gets an error for being ambiguous. I still can't find
the other override.


Norman Diamond said:
There's no difference between Microsoft's definitions of _TCHAR and TCHAR.
From the point of view of hypothetical possible conformance to standards
some day, implementations are free to define identifiers like _TCHAR
however they like, but like TCHAR. Either way my program is obviously
implementation dependant.

This project is not a Unicode build. I didn't test to see if Visual
Studio might work with this if it were Unicode. But this is old code and
there's neither funding nor time to convert it from ANSI (code page 932)
to Unicode.
Does char c = s[1] work?

I didn't try it, but: Wouldn't it be an even bigger WTF if
CSimpleStringT::blush:perator[] would disambiguate itself (wherever the
ambiguity is, which I haven't found) on account of something that's going
to happen to the resulting rvalue after it crosses to the other side of
the assignment operator to get stored?


Jonathan Wood said:
That syntax has always worked for me. I'm not familiar with _TCHAR--I
just use TCHAR.

Not really sure where the ambiguity comes in. Are you building Unicode?
Does char c = s[1] work? Does TCHAR c = s[0] work ???

--
Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com


Norman Diamond said:
In an antique obsolete version of MFC, a CString expression could be
subscripted in order to retrieve one element.

Visual Studio 2005 defines CSimpleStringT::blush:perator[]. At first glance
it looks like it might have been intended to provide backwards
compatibility for antique programs. But there seems to be no way to use
it.

CString s = _T("ab");
short i = 1;
_TCHAR c = s;

Error C2666, ambiguous overload.

In atlsimpstr.h I find one whole uniguous overload of operator[]. In
cstringt.h I find none. Where is the other one, and is there any way to
overcome it?


 
T

Tom Serface

To be honest, I'm not sure if [ ] works or not since I don't use it. I tend
to think of a CString as an object rather than an array so GetAt() always
made sense to me. I haven't heard anything about it not working through and
it used to be that the operator [ ] was just calling GetAt() anyway. I'll
try some tests tomorrow since now I'm curious :blush:)

Tom
 
T

Tom Walker

CString s = _T("ab");
short i = 1;
_TCHAR c = s;

Error C2666, ambiguous overload.


The compiler sees an ambiguity between these two possibilities:

_TCHAR c = s.operator[](i);
_TCHAR c = s.operator LPCTSTR();
 
N

Norman Diamond

[Norman Diamond:]
CString s = _T("ab");
short i = 1;
_TCHAR c = s;

Error C2666, ambiguous overload.


The compiler sees an ambiguity between these two possibilities:

_TCHAR c = s.operator[](i);
_TCHAR c = s.operator LPCTSTR();


Thank you, though i am short of complete understanding. If i is changed to
an int then it works. So disambiguation occurs before the integral
promotion, and disambiguation fails because the conversion from short to int
ranks equally with the user-defined cast operator? ("user-defined" from the
standard's point of view because operator LPCTSTR comes from MFC not from
the standard.)
 
N

Norman Diamond

David Wilkinson said:
Norman said:
In an antique obsolete version of MFC, a CString expression could be
subscripted in order to retrieve one element.

Visual Studio 2005 defines CSimpleStringT::blush:perator[]. At first glance
it looks like it might have been intended to provide backwards
compatibility for antique programs. But there seems to be no way to use
it.

CString s = _T("ab");
short i = 1;
_TCHAR c = s;

Error C2666, ambiguous overload.

In atlsimpstr.h I find one whole uniguous overload of operator[]. In
cstringt.h I find none. Where is the other one, and is there any way to
overcome it?


Norman:

Why the short?


The program is almost as antique as VC++6, I don't know the creator owner[*]
or most of the other intervening maintainers, and I'm not going to ask the
creator owner[**] to get the answer, sorry.

[* i.e. the creator]
[** i.e. the owner]
Surely it works if you do

CString s = _T("ab");
int i = 1;
TCHAR c = s;


Yup, it did, as I posted last night, and Tom Walker partly explained.
 
T

Tom Serface

The reason it doesn't work is because it's not really an array with an
index, it's a template and there is no overload for short (or anything other
than int for that matter) for that operator.

Nice pun by the way... "short of complete understanding"...

:blush:)

Tom

Norman Diamond said:
[Norman Diamond:]
 
N

Norman Diamond

it's not really an array

I know, but i still expected quick promotion to int.
Nice pun by the way... "short of complete understanding"...

Together with using the identifier instead of pronoun.


Tom Serface said:
The reason it doesn't work is because it's not really an array with an
index, it's a template and there is no overload for short (or anything
other than int for that matter) for that operator.

Nice pun by the way... "short of complete understanding"...

:blush:)

Tom

Norman Diamond said:
[Norman Diamond:]
Thank you, though i am short of complete understanding. If i is changed
to an int then it works. So disambiguation occurs before the integral
promotion, and disambiguation fails because the conversion from short to
int ranks equally with the user-defined cast operator? ("user-defined"
from the standard's point of view because operator LPCTSTR comes from MFC
not from the standard.)
 
D

Doug Harrison [MVP]

[Norman Diamond:]
CString s = _T("ab");
short i = 1;
_TCHAR c = s;

Error C2666, ambiguous overload.


The compiler sees an ambiguity between these two possibilities:

_TCHAR c = s.operator[](i);
_TCHAR c = s.operator LPCTSTR();


Thank you, though i am short of complete understanding. If i is changed to
an int then it works. So disambiguation occurs before the integral
promotion, and disambiguation fails because the conversion from short to int
ranks equally with the user-defined cast operator? ("user-defined" from the
standard's point of view because operator LPCTSTR comes from MFC not from
the standard.)


I believe this fragment models your example:

struct X
{
int operator[](int);
operator int*();
};

void f(X& x)
{
int y = x[short(1)];
}

VC8 emits the error:

X>cl -c a.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for
80x86

Copyright (C) Microsoft Corporation. All rights reserved.

a.cpp
a.cpp(9) : error C2666: 'X::blush:perator []' : 2 overloads have similar
conversions
a.cpp(3): could be 'int X::blush:perator [](int)'
or 'built-in C++ operator[(int *, short)'
while trying to match the argument list '(X, short)'

This is a bug. Both candidate functions require promotion of short to int,
but the operator[] is an exact match for the implicit object parameter,
while the conversion operator requires conversion of it to int*, which is
worse. (Reading the error message literally, it's like the compiler ignores
the user-defined conversion that occurs when it applies operator*, and to
make matters worse, ignores the fact that short is promoted to int, so
there cannot be any such "signature" for the built-in operator.) Because
operator[] provides a better match on one of the arguments and isn't worse
on the other, it should be selected. You might want to report this here:

http://connect.microsoft.com/feedback/default.aspx?SiteID=210

Post back with the URL, and I'll verify it.
 
N

Norman Diamond

Hi Tom,
thank you: so X = Ansi strings, and Y = Unicode strings, in the ATL
standard.

My understanding was:
X = T strings (i.e. in an ANSI compilation X = ANSI, and in a Unicode
compilation X = Unicode)
Y = the opposite (i.e. in an ANSI compilation Y = Unicode, and in a Unicode
compilation X = ANSI).

But it doesn't matter. The effect in this case still yields a definition of
operator LPCTSTR, implementing what the MSDN documentation says is
implemented. In my experience MSDN is about 75% accurate, and this
particular case is in those 75%.

The failure of operator [] is due to the compiler's confusion in promoting
shorts to ints, not due to confusion between X and T.

Since a Visual C++ 2005 compiler bug is involved, I have restored
microsoft.public.dotnet.languages.vc in the newsgroups that this is posted
to, instead of just the MFC newsgroup.
 
N

Norman Diamond

Norman Diamond said:
My understanding was:
X = T strings (i.e. in an ANSI compilation X = ANSI, and in a Unicode
compilation X = Unicode)
Y = the opposite (i.e. in an ANSI compilation Y = Unicode, and in a
Unicode compilation X = ANSI).

That last X should be a Y. In a Unicode compilation Y = ANSI.
 
N

Norman Diamond

Mr. Harrison, thank you for your analysis and recommendation, but there are
two reasons why I am not likely to submit this to the Connect site. If you
are sure that this is a compiler bug and if you think there's a chance of
getting it fixed, you obviously have a repro case and there would be nothing
wrong if you submit it to the Connect site.

Until I have time to read and interpret sections of the standard on overload
resolution and its relationship to standard integral promotions, I will not
feel confident in making an assertion myself that this is a compiler bug
(though I can still call it suspicious).

Also Microsoft has told me, in the Connect site for Visual Studio bugs, that
Microsoft cannot deal with an error message that Microsoft displays in
Japanese, even when I provided Microsoft with a rough translation of
Microsoft's error message into English. Microsoft has given some of my
Connect submissions on Visual Studio better treatment than my submissions on
Vista, but I still don't feel encouraged to waste too much time on it.
 
D

Doug Harrison [MVP]

Mr. Harrison, thank you for your analysis and recommendation, but there are
two reasons why I am not likely to submit this to the Connect site. If you
are sure that this is a compiler bug and if you think there's a chance of
getting it fixed, you obviously have a repro case and there would be nothing
wrong if you submit it to the Connect site.

Until I have time to read and interpret sections of the standard on overload
resolution and its relationship to standard integral promotions, I will not
feel confident in making an assertion myself that this is a compiler bug
(though I can still call it suspicious).

Also Microsoft has told me, in the Connect site for Visual Studio bugs, that
Microsoft cannot deal with an error message that Microsoft displays in
Japanese, even when I provided Microsoft with a rough translation of
Microsoft's error message into English. Microsoft has given some of my
Connect submissions on Visual Studio better treatment than my submissions on
Vista, but I still don't feel encouraged to waste too much time on it.

As it turns out, it was already reported, and it appears to have been fixed
(post SP1, though):

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=238447
 
Top