Implicit Boxing

The Visual C++ compiler now boxes value types to Object. This is possible because of a compiler-defined conversion to convert value types to Object.

Remarks

Boxing and unboxing enable value types to be treated as objects. Value types, including both struct types and built-in types such as int, can be converted to and from the type Object.

For more information, see:

Example

The following sample shows how explicit boxing was done with Managed Extensions for C++.

// vcmcppv2_explicit_boxing.cpp
// compile with: /clr:oldSyntax
using namespace System;

__gc class A {
public:
   void func(System::Object * o){Console::WriteLine("in A");}
};

__value class V {};

__gc __interface IFace {
   void func();
};

__value class V1 : public IFace   {
public:
   void func() {
      Console::WriteLine("Interface function");
   }
};

int main() {
   // example 1 explicit boxing
   Int32 __box* bi = __box(1);
   Console::WriteLine(bi);

   // example 2 calling a member with explicit boxing
  Int32 n = 10;
   Console::WriteLine(S"xx = {0}", __box(n)->ToString());

   // example 3 explicit boxing for function calls
   A * a = new A;
   a->func(__box(n));

   // example 4  explicit boxing for WriteLine function call
   V v;
   Console::WriteLine(S"Class {0} passed using implicit boxing", __box(v)->ToString());

   // example 5 casting to a base with explicit boxing
   V1 v1;
   IFace * iface = __box(v1);
   iface->func();
}

1 xx = 10 in A Class V passed using implicit boxing Interface function

The following sample shows how implicit boxing works.

// vcmcppv2_explicit_boxing2.cpp
// compile with: /clr
using namespace System;

ref class A {
public:
   void func(System::Object^ o){Console::WriteLine("in A");}
};

value class V {};

interface struct IFace {
   void func();
};

value class V1 : public IFace {
public:
   virtual void func() {
      Console::WriteLine("Interface function");
   }
};

value struct V2 {
   // conversion operator to System::Object
   static operator System::Object^(V2 v2) {
      Console::WriteLine("operator System::Object^");
      return (V2^)v2;
   }
};

void func1(System::Object^){Console::WriteLine("in void func1(System::Object^)");}
void func1(V2^){Console::WriteLine("in func1(V2^)");}

void func2(System::ValueType^){Console::WriteLine("in func2(System::ValueType^)");}
void func2(System::Object^){Console::WriteLine("in func2(System::Object^)");}

int main() {
   // example 1 simple implicit boxing
   Int32^ bi = 1;
   Console::WriteLine(bi);

   // example 2 calling a member with implicit boxing
   Int32 n = 10;
   Console::WriteLine("xx = {0}", n.ToString());

   // example 3 implicit boxing for function calls
   A^ a = gcnew A;
   a->func(n);

   // example 4 implicit boxing for WriteLine function call
   V v;
   Console::WriteLine("Class {0} passed using implicit boxing", v);
   Console::WriteLine("Class {0} passed with forced boxing", (V^)(v));   // force boxing

   // example 5 casting to a base with implicit boxing
   V1 v1;
   IFace ^ iface = v1;
   iface->func();

   // example 6 user-defined conversion preferred over implicit boxing for function-call parameter matching
   V2 v2;
   func1(v2);   // user defined conversion from V2 to System::Object preferred over implicit boxing
                // Will call void func1(System::Object^);

   func2(v2);   // OK: Calls "static V2::operator System::Object^(V2 v2)"
   func2((V2^)v2);   // Using explicit boxing: calls func2(System::ValueType^)
}

1 xx = 10 in A Class V passed using implicit boxing Class V passed with forced boxing Interface function in func1(V2^) in func2(System::ValueType^) in func2(System::ValueType^)

Requirements

Compiler option: /clr

See Also

Concepts

Language Features for Targeting the CLR