C++11 Mapping for Structures

A Slice structure maps to a C++ structure.

On this page:

Struct Mapping

Slice structures map to C++ structures with the same name. For each Slice data member, the C++ structure contains a public data member. For example, here is our Employee structure once more:

Slice
struct Employee 
{
    long number;
    string firstName;
    string lastName;
}

The Slice-to-C++ compiler generates the following definition for this structure:

C++
struct Employee
{
    long long int number;
    std::string firstName;
    std::string lastName;
 
	std::tuple<const long long int&, const ::std::string&, const ::std::string&> ice_tuple() const;
};

For each data member in the Slice definition, the C++ structure contains a corresponding public data member of the same name. Constructors are intentionally omitted so that the C++ structure qualifies as a plain old datatype (POD).

Comparison Operators

The generated C++ structures use templated comparison operators included from Ice.

C++ Comparison Operators
// !=, <, <=, >, >=  are implemented in the same manner 
template<class C, typename = std::enable_if<std::is_member_function_pointer<decltype(&C::ice_tuple)>::value>>
bool operator==(const C& lhs, const C& rhs)
{
   return lhs.ice_tuple() == rhs.ice_tuple();
}

These operators compare a std::tuple returned by the generated ice_tuple() function.

Generated ice_tuple
std::tuple<const long long int&, const ::std::string&, const ::std::string&> ice_tuple() const
{
    return std::tie(number, firstName, lastName);
}

Constructors and Assignment Operators

Copy construction and assignment always have deep-copy semantics. You can freely assign structures or structure members to each other without having to worry about memory management. The following code fragment illustrates both comparison and deep-copy semantics:

C++
Employee e1, e2;
e1.firstName = "Bjarne";
e1.lastName = "Stroustrup";
e2 = e1;                        // Deep copy
assert(e1 == e2);
e2.firstName = "Andrew";        // Deep copy
e2.lastName = "Koenig";         // Deep copy
assert(e2 < e1);

Because strings are mapped to std::string, there are no memory management issues in this code and structure assignment and copying work as expected. (The default member-wise copy constructor and assignment operator generated by the C++ compiler do the right thing.)

Default Constructors

Structures have an implicit default constructor that default-constructs each data member. Members having a complex type, such as strings, sequences, and dictionaries, are initialized by their own default constructor. However, the default constructor performs no initialization for members having one of the simple built-in types boolean, integer, floating point, or enumeration. For such a member, it is not safe to assume that the member has a reasonable default value. This is especially true for enumerated types as the member's default value may be outside the legal range for the enumeration, in which case an exception will occur during marshaling unless the member is explicitly set to a legal value.

To ensure that data members of primitive types are initialized to reasonable values, you can declare default values in your Slice definition. These default values are mapped to C++ data member initializers.

See Also