System::String Handling in Visual C++
This topic discusses how the Visual C++ compiler processes string literals when you run it by using the /clr compiler option. To use /clr, you must also use the common language runtime (CLR), C++/CLI syntax and managed objects. For more information about /clr, see /clr (Common Language Runtime Compilation).
Remarks
When compiling with /clr, the compiler will convert string literals to strings of type String. To preserve backward compatibility with existing code there are two exceptions to this:
Exception handling. When a string literal is thrown, the compiler will catch it as a string literal.
Template deduction. When a string literal is passed as a template argument, the compiler will not convert it to a String. Note, string literals passed as a generic argument will be promoted to String.
The compiler also has built-in support for three operators, which you can override to customize their behavior:
System::String ^ operator +( System::String, System::String);
System::String ^ operator +( System::Object, System::String);
System::String ^ operator +( System::String, System::Object);
When passed a String, the compiler will box, if necessary, and then concatenate the object (with ToString) with the string.
When compiling with /clr:oldSyntax, string literals will not be converted to String.
Notes
The caret ("^") indicates that the declared variable is a handle to a C++/CLI managed object.
For more information see C++ String Literals.
Example
// string_operators.cpp
// compile with: /clr
// In the following code, the caret ("^") indicates that the
// declared variable is a handle to a C++/CLI managed object.
using namespace System;
int main() {
String ^ a = gcnew String("abc");
String ^ b = "def"; // same as gcnew form
Object ^ c = gcnew String("ghi");
char d[100] = "abc";
// variables of System::String returning a System::String
Console::WriteLine(a + b);
Console::WriteLine(a + c);
Console::WriteLine(c + a);
// accessing a character in the string
Console::WriteLine(a[2]);
// concatenation of three System::Strings
Console::WriteLine(a + b + c);
// concatenation of a System::String and string literal
Console::WriteLine(a + "zzz");
// you can append to a System::String ^
Console::WriteLine(a + 1);
Console::WriteLine(a + 'a');
Console::WriteLine(a + 3.1);
// test System::String ^ for equality
a += b;
Console::WriteLine(a);
a = b;
if (a == b)
Console::WriteLine("a and b are equal");
a = "abc";
if (a != b)
Console::WriteLine("a and b are not equal");
// System:String ^ and tracking reference
String^% rstr1 = a;
Console::WriteLine(rstr1);
// testing an empty System::String ^
String ^ n;
if (n == nullptr)
Console::WriteLine("n is empty");
}
abcdef abcghi ghiabc c abcdefghi abczzz abc1 abc97 abc3.1 abcdef a and b are equal a and b are not equal abc n is empty
The following sample shows that you can overload the compiler-provided operators, and that the compiler will find a function overload based on the String type.
// string_operators_2.cpp
// compile with: /clr
using namespace System;
// a string^ overload will be favored when calling with a String
void Test_Overload(const char * a) {
Console::WriteLine("const char * a");
}
void Test_Overload(String ^ a) {
Console::WriteLine("String ^ a");
}
// overload will be called instead of compiler defined operator
String ^ operator +(String ^ a, String ^ b) {
return ("overloaded +(String ^ a, String ^ b)");
}
// overload will be called instead of compiler defined operator
String ^ operator +(Object ^ a, String ^ b) {
return ("overloaded +(Object ^ a, String ^ b)");
}
// overload will be called instead of compiler defined operator
String ^ operator +(String ^ a, Object ^ b) {
return ("overloaded +(String ^ a, Object ^ b)");
}
int main() {
String ^ a = gcnew String("abc");
String ^ b = "def"; // same as gcnew form
Object ^ c = gcnew String("ghi");
char d[100] = "abc";
Console::WriteLine(a + b);
Console::WriteLine(a + c);
Console::WriteLine(c + a);
Test_Overload("hello");
Test_Overload(d);
}
overloaded +(String ^ a, String ^ b) overloaded +(String ^ a, Object ^ b) overloaded +(Object ^ a, String ^ b) String ^ a const char * a
The following sample shows that the compiler distinguishes between native strings and String strings.
// string_operators_3.cpp
// compile with: /clr
using namespace System;
int func() {
throw "simple string"; // const char *
};
int func2() {
throw "string" + "string"; // returns System::String
};
template<typename T>
void func3(T t) {
Console::WriteLine(T::typeid);
}
int main() {
try {
func();
}
catch(char * e) {
Console::WriteLine("char *");
}
try {
func2();
}
catch(String^ str) {
Console::WriteLine("String^ str");
}
func3("string"); // const char *
func3("string" + "string"); // returns System::String
}
char * String^ str System.SByte* System.String
Requirements
Compiler option: /clr
See Also
Reference
/clr (Common Language Runtime Compilation)