Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

CString::operator[] ambiguity.

Posted on 1998-08-07
14
Medium Priority
?
1,065 Views
Last Modified: 2013-11-20
I have the following line of code, which causes me trouble:
char charCurrent = strPathName[i];

strPathName is a CString.

It generates this error:
...(156) : error C2666: '[]' : 2 overloads have similar conversions (new behavior; please see help)

Help on "Compiler Error C2666" gave me this:
{
'identifier' : number overloads have similar conversions
The specified overloaded function or operator was ambiguous. If you’ve encountered this error on code which compiled with an earlier version of Visual C++, please read Technote: Improved Conformance to ANSI C++ for more information.
This error is caused by formal parameter lists that are too similar to resolve ambiguity.
An explicit cast of one or more of the actual parameters can resolve the ambiguity.
The following is an example of this error:
 
void func( int, float ) {};
void func( float, int ) {};
func( 1, 1 );        // error, same conversion for each func
func( 1, (float)1 )  // OK
}

CString::operator[] is declared:
TCHAR operator[](int nIndex) const; // same as GetAt

I looked up TCHAR, and it is typedef'd as char.

I know I can use GetAt without problem, but why should I have to?

I only see 1 operator[]. Which "2 overloads" is it talking about? Even if there are more than 1, why would it cause ambiguity? How do I make it not ambiguous?

I've had this problem before in an other class that had a const and non-const operator[]. This doesn't even seem to be the case. What's up?
0
Comment
Question by:TylerRick
  • 5
  • 3
  • 2
  • +2
14 Comments
 
LVL 7

Expert Comment

by:psdavis
ID: 1320421
Here's a sniplet from the class definition.  The real question that I want to know is what is 'i'?  If it is a true 'int', then I would doubt that you would get the error, but you're right, this is a enigma.

char charCurrent = strPathName[i];

class CString
{
public:
// Constructors
      CString();
      CString(const CString& stringSrc);

// Attributes & Operations
      TCHAR GetAt(int nIndex) const;      // 0 based
      TCHAR operator[](int nIndex) const; // same as GetAt
      void SetAt(int nIndex, TCHAR ch);
.
};

Phillilp

0
 
LVL 22

Expert Comment

by:nietod
ID: 1320422
The thing that confuses me is that CString::operator[] is not overloaded.  There aren't two overloads for it to choose between.  Are you sure that strPathName is a CString?  can you post a large code sample?
0
 
LVL 8

Expert Comment

by:trestan
ID: 1320423
In afx.h, [] is declared only once, but in afxcoll.h, this operator is overloaded (pls check it for detail). The stdafx.h include the libs. That is why the error message. To correct it, just explicitly use int or const to cast the index number i. char charCurrent = strPathName[(int)i]; the error should disappear.

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:TylerRick
ID: 1320424
trestan, I checked afxcoll.h and class CString is not declared there. It is declared in afx.h.
These classes are in afxcoll.h:
class CStringArray;         // array of CStrings
class CStringList;          // list of CStrings
I believe the "coll" means collections, which CString is not.

>The thing that confuses me is that CString::operator[] is not overloaded.
Right, I still believe that there is only 1 CString::operator[]. Don't ask me why. Shouldn't there be a const and non-const, like there is for, say, CStringArray?

>To correct it, just explicitly use int or const to cast the index number i. char charCurrent = strPathName[(int)i]; the error should disappear.
Yes, that worked to get rid of the error message. Thanks for that, trestan.

Sorry I didn't say what i was before. It is:
unsigned short int

I guess that explains it, huh? I guess my problem was that my i (unsigned short int) is not a true "int" (signed short int?) as Phillilp suggested.

But I still would like to know why there is ambiguity if there is only 1 operator[] defined? The error said there were "2 overloads", which, as far as I can tell, there are not! Can some one explain what is going on? Or is the compiler just confused?


0
 
LVL 32

Expert Comment

by:jhance
ID: 1320425
You've got some other problem elsewhere in your code.  The following code compiles OK.  Post your declaration of strPathName.

      CString strPathName;
      strPathName = "Testing";

      for(int i=0; i<5; i++){
            TCHAR charCurrent = strPathName[i];
      }
0
 
LVL 22

Expert Comment

by:nietod
ID: 1320426
Does it work if you make your counter an unsigned short int?  That would be a good test.  
0
 
LVL 22

Expert Comment

by:nietod
ID: 1320427
I tested and I have the same problem with an unsigned short index.


>>Shouldn't there be a const and non-const, like there is for, say, CStringArray?
No because the operator does nto return a reference to a character in the string, it returns a copy of the character in the string.  that means that if you try

SomeString[2] = 'a';

however, it won't work.  The [] operator can be used to "examine" characters in the string, but can't be used to change them.  If it could, that is if it returned a reference to a character from the string rather than a copy, then yes, you would need a const and non-const version of operator [].
0
 
LVL 22

Expert Comment

by:nietod
ID: 1320428
The only explanation I can think of--and certainly can't confirm-- is that since the CString does't have another overload for operator [] , that there is a a global (non-class) operator [] overload somewhere.  And that what the compiler 's other option is, is to convert the CString to the type used by the global operator [].  That's assuming that [] isn't required to be part of a class.  I didn't look that up.
0
 
LVL 8

Expert Comment

by:trestan
ID: 1320429
Have you tried to use the casts? Actually a "long" type index also cause such problems. I use the "int" or "const" casting to solve the problem. As of the reasons, I guess that the overload [] in CStringArray may have some influence to its usage on CString. For the radical reason, I think you have to ask MS.
0
 
LVL 32

Expert Comment

by:jhance
ID: 1320430
nietod,

Why do you insist that CString doesn't have an overloaded operator []?  If you look in Afx.h you will see the following in class CString:

      TCHAR GetAt(int nIndex) const;      // 0 based
      TCHAR operator[](int nIndex) const; // same as GetAt

This looks like an overloaded [] operator to me.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1320431
That is a single overload. Where is the ambiguity?  The error suggests that it can't decide between two overloaded functions, what is the second one?
0
 

Author Comment

by:TylerRick
ID: 1320432
>You've got some other problem elsewhere in your code.  The
>following code compiles OK.  Post your declaration of
>strPathName.

strPathName is a parameter in my function:
CString
FindFileName(CString strPathName)
{
      CString strFileName;

      for (unsigned short int i = strPathName.GetLength() - 1; i >= 0; i--)
      {
            char charCurrent = strPathName[i];  
            if (charCurrent == '\\')
            {
                  break;
            }
      }
      
      strFileName = strPathName.Mid(i + 1);
      
      return strFileName;
}

jhance's example:
{
CString strPathName;
strPathName = "Testing";

for(int i=0; i<5; i++){
TCHAR charCurrent = strPathName[i];
}
Right, that works because i is signed. I don't want my i signed because it will never go < 0. I'm getting in trouble because I don't just use "int" like most people; I'm specifying "signed".

>That is a single overload. Where is the ambiguity?  The error
>suggests that it can't decide between two overloaded functions,
>what is the second one?
My point exactly!

>I tested and I have the same problem with an unsigned short
>index.  
Apparently, it won't work unless it has an int (signed instead of unsigned). I guess I'm stuck with the solution of casting:
char charCurrent = strPathName[(int)i];
Which works fine.

>No because the operator does nto return a reference to a
>character in the string, it returns a copy of the character in
>the string.  
I get it. I think it would be better if they let you use [] for changing part of the string as well.

It looks like no one has answer for why it can't implicitly cast to the required type, why it needs an explicit cast. Oh well, at least it compiles. That's what matters, I guess. Thanks all for the help!

Who wants the points? nietod?
0
 
LVL 32

Accepted Solution

by:
jhance earned 180 total points
ID: 1320433
>>It looks like no one has answer for why it can't implicitly cast to the required type

If you have a copy of Stroustruop's C++ Programming Language book, sections 6.2 (Operator Functions) and 6.3 (User-defined Type Conversion) give details (in fairly roudabout language) as to why your implicit conversion is not allowed.  I'm sure that there is an even more obtuse explanation in the C++ LRM if you're interested.


0
 
LVL 7

Expert Comment

by:psdavis
ID: 1320434
We all want the points, but I think nietod wins on volume.

Phillip
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
Ready to get certified? Check out some courses that help you prepare for third-party exams.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Want to learn how to record your desktop screen without having to use an outside camera. Click on this video and learn how to use the cool google extension called "Screencastify"! Step 1: Open a new google tab Step 2: Go to the left hand upper corn…

773 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question