1

I want to create a wrapperClass for strings. I also want the class to be able to return the address of the wrapperClass and the address of the stored (wrapped) string:

void FunctionString(string*);
void FunctionWrappedString(wrappedString*);

int main(){
   wrappedString wrappedStringObject;

   FunctionString(&wrappedStringObject);
   FunctionWrappedString(&wrappedStringObject);

   wrappedString anotherWrappedStringObject;

   if(wrappedStringObject == anotherWrappedStringObject){
    // code
   }
}

Here are the important parts of the class:

class wrappedString{
   typedef char* string;

   string storedString;

   operator string*(){
      // some code
      return &storedString;
   }

   operator wrapperString*(){
      // some code
      return this;
   }

  operator string(){
    // some code
    return storedString;
  }

}

However these fail when I use the comparison operator:

if(wrappedStringObject == anotherWrappedStringObject){
  // code
}

Saying that the candidates are: operator==(string,string) and operator==(string*,string*)

  • 1
    Some friendly advice -- too many casting operators will lead to many unforseen issues, even if you do get this to compile successfully. Things such as code that gets invoked that you didn't expect is just one of them. If you want to return a `std::string`, have a function call `get_string` instead of a cast to `string()`. – PaulMcKenzie Jun 21 '16 at 23:54
  • @PaulMcKenzie: Or alternatively, define the casting operator, but make all (or all but one or two) cases `explicit` (requires C++11). `explicit operator std::string*`, `explicit operator std::string`, etc. – ShadowRanger Jun 21 '16 at 23:58
  • 2
    Side-note: `typedef char* string;`?!? Why? That's just a great way to confuse the crap out of users; your `if(wrappedStringObject == anotherWrappedStringObject)`, even if it works, ends up testing that two `char*` are pointers to the same _memory address_, not pointers to strings with the same _contents_. – ShadowRanger Jun 22 '16 at 00:03
  • I want to be able to plug this class into char* functions without much problems or code modification. @ShadowRanger Thanks for for showing the explicit keyword. Adding the (string*) everytime is still less than ideal, but at least it works. – ClemsonCoder Jun 22 '16 at 01:22
  • @ClemsonCoder: That usage doesn't necessarily require casting, assuming you're okay with never getting the address of the wrapper itself, just [by overloading `operator&`](https://stackoverflow.com/questions/6495977/what-legitimate-reasons-exist-to-overload-the-unary-operator) (this is basically the only legitimate case for doing so). Doing so would make `&mywrappedstring` produce a `char**` (aka `string*` with your `typedef`) referencing the member of the wrapper object. – ShadowRanger Jun 22 '16 at 01:45
  • @ShadowRanger I tried that, however I want to be able to get the address of the wrapper class when the function requires a pointer to a wrapper class object and I want to be able to get the address of the wrapped string when the function requires a pointer to a string. If I could just disable one or some of the == operator overloads it would be fine. – ClemsonCoder Jun 25 '16 at 17:52
  • @ClemsonCoder: Well, `std::addressof` bypasses overloaded `operator&`, so when you really, really need the address of the wrapper object, you could still do it. – ShadowRanger Jun 26 '16 at 13:22

1 Answers1

0

Multiple implicit cast operators are causing this problem. If the goal is to have the wrapped string object behave like a string (which is actually a char*?!?), then only allow one implicit cast operator, while leaving the rest explicit to reduce the risk of misbehavior. This only works on C++11, but you should be using that by now anyway:

class wrappedString{
   typedef char* string;

   string storedString;

   explicit operator string*(){
      // some code
      return &storedString;
   }

   explicit operator wrapperString*(){
      // some code
      return this;
   }

   operator string(){
     // some code
     return storedString;
   }

}

With that definition, if(wrappedStringObject == anotherWrappedStringObject){ will only use the string overload, not the string* overload.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271