RTI Connext Modern C++ API  Version 5.3.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Working with IDL types

How IDL types map to C++ classes. More...


class  Foo
 A hypothetical topic-type. More...

Detailed Description

How IDL types map to C++ classes.

Example IDL types

The following IDL code defines the types we will use in these examples.

struct Foo {
long x; //@key
long y;
struct MyType {
long my_long;
string<512> my_string;
Foo my_foo;
sequence<long, 10> my_sequence;
Foo my_array[5];
Foo my_optional; //@Optional

To generate C++ code for these types see Create user data types using rtiddsgen

Constructors and operators

C++ types generated from IDL have value semantics and provide a default constructor, a copy constructor, a move constructor <<C++11>>, a constructor with parameters to set all the type's members, a destructor, a copy-assignment operator, and a move-assignment operator <<C++11>>. Types also include equality operators, the operator << to std::ostream <<extension>> and a namespace-level swap function.

// The default constructor recursively initializes all members of a sample
MyType default_sample;
// A copy constructor is also provided
MyType copied_sample = default_sample;
// For convenience, another constructor allows initializing all the members
MyType initialized_sample (
7, // my_long
std::string("Hello, World!"), // my_string
Foo(1, 2), // my_foo (initializing its members 'x' and 'y')
std::vector<int32_t>(3, 2), // my_sequence containing 3 times the value 2
dds::core::array<Foo, 5>(), // my_array
Foo(2, 3) // my_optional (initialized with a non-empty value)
// An assignment operator is also available
copied_sample = initialized_sample;
// Equals operator (!= also available)
if (copied_sample == initialized_sample) {
std::cout << "Samples are equal\n";
std::cout << "You can print samples to an output stream: "
<< copied_sample
<< std::endl;

In addition to that, a number of traits provide additional information and utilities for IDL-generated types.

Accessing the type members

Setters and getters allow accessing the type members.

The following table summarizes how different IDL types map to C++. The mapping is different depending on whether the option "-stl" is specified or not:

IDL type C++ type (with -stl) C++ type (without -stl)
string std::string dds::core::string
bounded sequence (sequence<T, M>) rti::core::bounded_sequence<T, M> dds::core::vector<T>
unbounded sequence (sequence<T>) std::vector<T> dds::core::vector<T>
array (T member[N]) dds::core::array<T, N> same
optional annotation (T member; //@optional) dds::core::optional<T> same
external annotation (T member; //@external) dds::core::external<T> T*

The type rti::core::bounded_sequence offers similar functionality to that of a std::vector. But because it has an upper bound M, it provides two advantages:

1) A better memory management strategy for deserializing data samples in a DataReader, improving the overall performance of the middleware.

2) Its member functions check for out-of-bounds growth.

It is possible to use std::vector for bounded sequences by annotating them with @use_vector in IDL. For example:

struct Foo {
@use_vector sequence<long, 10> bounded_sequence_as_vector;
sequence<long, 10> bounded_sequence;
sequence<long> unbounded_sequence;

The type dds::core::array is just an alias of std::array if supported by the compiler, or an alias of boost::array otherwise.

The following example shows how to use getters and setters and work with different IDL types.

MyType my_sample;
// Access a primitive type
if (my_sample.my_long() == 0) { // getter
my_sample.my_long(1); // setter
// Access a string
my_sample.my_string() = "Hello, World!"; // reference getter
std::cout << "my_string: " << my_sample.my_string() << std::endl;
// Access nested type
std::cout << "my_foo.x: " << my_sample.my_foo().x() << std::endl;
my_sample.my_foo().x(3); // set a member of the nested type
my_sample.my_foo() = Foo(1, 2); // or assign a full object
// Access a sequence
my_sample.my_sequence().resize(4); // by default length is zero
int my_ints[] = {3, 2, 4, 1};
std::copy(my_ints, my_ints + 4, my_sample.my_sequence().begin());
std::sort(my_sample.my_sequence().begin(), my_sample.my_sequence().end());
std::cout << "my_sequence[0]: " << my_sample.my_sequence()[0] << std::endl;
// Access an array
std::cout << "my_array[3]: " << my_sample.my_array()[3] << std::endl;
// Fill array with copies of Foo(4, 5)
std::fill(my_sample.my_array().begin(), my_sample.my_array().end(), Foo(4, 5));
// Access an optional member
if (!my_sample.my_optional().is_set()) { // by default, an optional member is unset
my_sample.my_optional(Foo(1, 2)); // assign a value
my_sample.my_optional() = Foo(1, 2); // this is equivalent
my_sample.my_optional().reset(); // make it empty
std::cout << "my_sample: " << my_sample << std::endl;

RTI Connext Modern C++ API Version 5.3.1 Copyright © Mon Feb 19 2018 Real-Time Innovations, Inc