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.
std::indirect
and std::polymorphic
have been accepted into the C++ draft standard and should be available in C++26.
P3019r14 was accepted in the Hagenburg meeting in 2025.
std::indirect
- cppreference documentationstd::polymorphic
- cppreference documentation
Prior work on standardizing similar types, indirect_value
and polymorphic_value
can be found at:
Design of these two types was so deeply coupled that subsequent work proceeded in the final unified paper.
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>
CompositeWithPolymorphicMembers(const Tx& x, const Ty& y) :
x_(std::in_place_type<Tx>, x),
y_(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>
We have C++14 implementations of indirect
and polymorphic
available as
indirect_cxx14.h
and polymorphic_cxx14.h
.
C++14 implementations can be tried out in Compiler Explorer by using the includes:
#include <https://raw.githubusercontent.com/jbcoe/value_types/main/indirect_cxx14.h>
#include <https://raw.githubusercontent.com/jbcoe/value_types/main/polymorphic_cxx14.h>
or by including headers indirect_cxx14.h
and polymorphic_cxx14.h
into your project.
We duplicate some code between the C++20 and C++14 implementations so that single-file includes work.
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 codespaces] (https://docs.github.com/en/codespaces/getting-started/deep-dive)
-
[ISO C++ Standard - Draft] (https://eel.is/c++draft/)