Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ equivalent of algebraic datatype?

Let's say I have this Haskell code:

data RigidBody = RigidBody Vector3 Vector3 Float Shape -- position, velocity, mass and shape
data Shape = Ball Float -- radius
           | ConvexPolygon [Triangle]

What would be the best way to express this in C++?

struct Rigid_body {
    glm::vec3 position;
    glm::vec3 velocity;
    float mass;
    *???* shape;
};

The thing I'm asking is how to represent shape inside the struct when it can be one of two types.

like image 974
user3133295 Avatar asked Dec 24 '13 19:12

user3133295


People also ask

What are the 4 data types in C?

The C language provides the four basic arithmetic type specifiers char, int, float and double, and the modifiers signed, unsigned, short, and long. The following table lists the permissible combinations in specifying a large set of storage size-specific declarations.

What is C datatype?

Advertisements. Data types in c refer to an extensive system used for declaring variables or functions of different types. The type of a variable determines how much space it occupies in storage and how the bit pattern stored is interpreted. The types in C can be classified as follows − Sr.No.

What are the 5 data types in C?

Most of the time, for small programs, we use the basic fundamental data types in C – int, char, float, and double. For more complex and huge amounts of data, we use derived types – array, structure, union, and pointer. Enumeration and void consist of enum and void, respectively.

What are the 3 data types in C?

Union, structure, array, etc. The basic data types are also known as the primary data types in C programming.


2 Answers

There are different approaches that can be used to solve that problem in C++.

The pure-OO approach you would define an interface Shape and have the two different options as derived types implementing that interface. Then the RigidBody would contain a pointer to a Shape that would be set to refer to either a Ball or a ConvexPolygon. Pro: people love OO (not sure this is a pro really :)), it is easily extensible (you can add more shapes later on without changing the type). Con: You should define a proper interface for Shape, it requires dynamic allocation of memory.

Putting OO aside, you can use a boost::variant or similar type, that is basically a tagged union that will hold one of the types. Pro: no dynamic allocations, shape is local to the object. Con: not pure-OO (people love OO, you remember right?), not so easy to extend, cannot use the shape generically

like image 155
David Rodríguez - dribeas Avatar answered Sep 20 '22 20:09

David Rodríguez - dribeas


To throw another possibility in here, you can also use boost::variant which is being added to the standard library in C++17 as std::variant:

struct Ball { float radius; };
struct ConvexPolygon { Triangle t; }

using Shape = boost::variant<Ball, ConvexPolygon>;

The advantages of this approach:

  • Type-safe, unlike tagged unions
  • Can hold complex types, unlike unions
  • Does not require a uniform interface across all "child" types, unlike OO

Some disadvantages:

  • Sometimes requires you to do a type check when accessing the variable to confirm that it is the type you want it to be, unlike OO
  • Requires you to use boost, or be C++17 compatible; these may be difficult with some compilers or some organizations where OO and unions are universally supported
like image 37
robbrit Avatar answered Sep 16 '22 20:09

robbrit