This repository contains two class templates: indirect
and polymorphic
. Both
templates are designed to be used for member data in composite types.
-
An instance of
indirect<T>
owns an object of classT
. -
An instance of
polymorphic<T>
owns an object of classT
or a class derived fromT
.
Both classes behave as value types and allow special member functions for a class that contains them as members to be generated correctly. Our experience suggests that use of these class templates can significantly decrease the burden of writing and maintaining error-prone boilerplate code.
indirect
and polymorphic
have been accepted into the C++ draft standard for
2026 as part of indirect
and polymorphic
: Vocabulary Types for Composite
Class Design
The reference implementation in this repository differs slightly from the proposal: we use concepts for requirements to support incomplete types in variants. We will submit a library issue to the C++ standard committee to amend the proposal.
The indirect
and polymorphic
class templates are header-only. To use them,
include the headers indirect.h
and polymorphic.h
in your project.
#include "indirect.h"
class Composite {
xyz::indirect<A> a_; // a_ owns an object of type A
xyz::indirect<B> b_; // b_ owns an object of type B
public:
Composite(const A& a, const B& b) :
a_(a),
b_(b) {}
// ...
};
#include "polymorphic.h"
class CompositeWithPolymorphicMembers {
xyz::polymorphic<X> x_; // x_ owns an object of type X or derived from X
xyz::polymorphic<Y> y_; // y_ owns an object of type Y or derived from Y
public:
template <typename Tx, typename Ty>
Composite(const Tx& x, const Ty& y) :
a_(std::in_place_type<Tx>, x),
b_(std::in_place_type<Ty>, y) {}
// ...
};
You can try out indirect
and polymorphic
in Compiler explorer
by adding the includes:
#include <https://raw.githubusercontent.com/jbcoe/value_types/main/indirect.h>
#include <https://raw.githubusercontent.com/jbcoe/value_types/main/polymorphic.h>
This code is licensed under the MIT License. See LICENSE for details.
We spoke about an earlier draft at C++ on Sea in 2022.
There are some significant design changes since this talk was given (after feedback and discussion at a C++ London meetup). We've pared down the number of constructors and made the null state unobservable.
For building and working with the project, please see the developer guide.
Press .
or visit [https://github.dev/jbcoe/value_types] to open the project in
an instant, cloud-based, development environment. We have defined a
devcontainer that will automatically install
the dependencies required to build and test the project.
-
[TK's allocator user guide] (https://rawgit.com/google/cxx-std-draft/allocator-paper/allocator_user_guide.html)
-
[A polymorphic value-type for C++] (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0201r5.html)
-
[indirect_value: A Free-Store-Allocated Value Type For C++] (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1950r2.html)
-
[GitHub codepsaces] (https://docs.github.com/en/codespaces/getting-started/deep-dive)
-
[ISO C++ Standard - Draft] (https://eel.is/c++draft/)