Constructors

  1. clair-c2py wraps all public constructors of a class.

  2. For C++ aggregates without user-defined constructors (i.e., structs with public fields only), clair-c2py synthesizes a constructor from a Python dict, mimicking in Python the C++ aggregate initialization syntax.

User-defined constructors

Let us first illustrate user-defined constructors with a simple example:

constructor_basic.cpp
#include <c2py/c2py.hpp>
class point {
  double x_, y_;

  public:
  point() : point(0, 0) {}                    // Default constructor
  point(double x, double y) : x_(x), y_(y) {} // Constructor with parameters

  double x() const { return x_; }
  double y() const { return y_; }
};

In Python, we get:

>>> from constructor_basic import Point
>>> p1 = Point()              # Default constructor
>>> p2 = Point(3.0, 4.0)      # Constructor with arguments
>>> p3 = Point(x=1.0, y=2.0)  # Keyword arguments
>>> print(p1.x(), p1.y())
0.0 0.0

Synthesized aggregate constructor

The second example illustrates the aggregate constructor:

constructor_aggregate.cpp
// Synthesized constructor from parameter struct
#include <c2py/c2py.hpp>
#include <string>

struct params {
  // The width
  int width;

  // The height
  int height;

  // Some boolean flag
  bool fullscreen = false;

  // A title
  std::string title = "Application";
};

In Python, we get:

>>> from constructor_aggregate import Params
>>> p = Params(width=800, height=600, fullscreen=True, title="My App")

The synthesized constructor accepts only keyword arguments and performs the following checks:

  • All fields without a default value must be initialized.

  • No unknown fields are allowed.

If any of these checks fail, a RuntimeError is raised.

>>> p = Params(height=600, fullscreen=True)
Traceback (most recent call last):
  ...
RuntimeError:
 Mandatory parameter 'width' is missing.

>>> p = Params(width=800, height=600, fullscreen=True, title="My App", extra=42)
Traceback (most recent call last):
  ...
RuntimeError:
 The parameter 'extra' was not used.