3

When working with Objective-C++, I often find myself using initWithCString to convert from std::string to NSString. To simplify the process, I created a category on NSString as follows:

@implementation NSString (NSStringFromCPP)

+(NSString*)stringFromCppString:(std::string)cppString
{
    return [[NSString alloc] initWithCString:cppString.c_str() encoding:NSStringEncodingConversionAllowLossy];
}


-(std::string)cppString
{
    return std::string([self cStringUsingEncoding:NSStringEncodingConversionAllowLossy]);
}

@end

This allows for a fairly easy conversion between NSString and std::string in both directions. It seems there has to be a way to implicitly convert from std::string to NSString though. I understand that there is no such thing as a constructor in Objective-C, so how might the following be accomplished without having to use stringFromCppString

-(void)something:(NSString*)someString
{
    NSLog(@"%@", someString);
}


-(void)activity
{
    std::string activityName = "Calculator";
    [self something:[NSString stringFromCppString:activityName]];
}

In most cases, code making use of std::string can be separated from code using NSString. However, there is a fair amount of bridging that occurs, and the code becomes distracting with stringFromCppString all over the place.

1
  • 1
    std::string s = ""; NSString *nsstr = @(s.c_str()); Commented Apr 23, 2014 at 0:02

2 Answers 2

3

You should pass std::string const & as the type for the parameter in your Obj-C method.

+(NSString*)stringFromCppString:(std::string const &)cppString;

Also, do not forget that when compiled as .mm, you can use normal C++, so you may want to consider something as simple as overloading...

std::string
cppString(char const *s)
{
  return s;
}

std::string const &
cppString(std::string const &s)
{
  return s;
}

std::string
cppString(NSString *s)
{
  return [self cStringUsingEncoding:DESIRED_ENCODING];
}

And the other way...

NSString *
objcString(char const *s)
{
  return [NSString stringWithCString:s encoding:DESIRED_ENCODING];
}

NSString *
objcString(std::string const &s)
{
  return objcString(s.c_str());
}

NSString *
objcString(NSString *s)
{
  return s;
}

Now, whenever you want a C++ std::string, just call cppString and whenever you want a Obj-C NSString, just call objcString, and you don't really have to care what the "real" string is...

Or, you could make your own string wrapper, with conversion operators, that you use... it would be pretty simple to do as well.

However, in general, you want probably your C++ to be C++, and your ObjC to be ObjC, and use .mm to act as a lightweight glue.

Sign up to request clarification or add additional context in comments.

Comments

2

Objective-C doesn't provide any facilities to implicitly convert between types. In fact, it doesn't even have the concept of casting an object — since all objects are referred to by pointers, casts are just pointer casts that don't change the underlying data. The only way the language provides to convert an object into some other type is to call a method on the object.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.