Value types for composite class design
March 15, 2026 ยท View on GitHub
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 classTor 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.
Standardization
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.
Documentation
std::indirect- cppreference documentationstd::polymorphic- cppreference documentation
Prior Work
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.
Use
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) {}
// ...
};
Compiler explorer
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>
Compatibility
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.
License
This code is licensed under the MIT License. See LICENSE for details.
Talks and presentations
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.
Contributing
For building and working with the project, please see the contributing guide.
GitHub codespaces
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.
References
-
[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/)