Slides for P3740R1
Last chance to fix std::nontype

Document number:
P3753R1
Date:
2025-06-20
Audience:
LEWG
Project:
ISO/IEC 14882 Programming Languages — C++, ISO/IEC JTC1/SC22/WG21
Reply-To:
Jan Schultke <janschultke@gmail.com>
Source:
github.com/Eisenwave/cpp-proposals/blob/master/src/nontype-slides.cow

This document has custom controls:

  • ,  ↓ : go to the next slide
  • ,  ↑ : go to previous slide

Last chance
to fix std::nontype
P3740R1

Jan Schultke  |  Slides for P3740R1 — Last chance to fix std::nontype  |  LEWG at Sofia 2025-06-20  |  Slide 1

Introduction

Conclusion

History is messy. std::nontype may be a bad feature now, or at least have a terrible name.

Jan Schultke  |  Slides for P3740R1 — Last chance to fix std::nontype  |  LEWG at Sofia 2025-06-20  |  Slide 2

std::function_ref refresher

std::function_ref is a "function wrapper" similar to std::function, std::move_only_function, std::copyable_function, but without ownership.


std::function_ref<R(Args...) cv noex> stores:

For illustration purposes, we'll ignore cv, noex, invoke.

Jan Schultke  |  Slides for P3740R1 — Last chance to fix std::nontype  |  LEWG at Sofia 2025-06-20  |  Slide 3

std::nontype in std::function_ref

template<class F> function_ref(F*); template<class F> function_ref(F&&); template<auto f> function_ref(nontype_t<f>); template<auto f, class U> function_ref(nontype_t<f>, U&&); template<auto f, class T> function_ref(nontype_t<f>, T*); template<auto f> function_ref(nontype_t<f>) { this->bound-entity = {}; this->thunk-ptr = [](BoundEntityType, Args&&... args) -> R { return f(std::forward<Args&&>(args)...); }; }
Jan Schultke  |  Slides for P3740R1 — Last chance to fix std::nontype  |  LEWG at Sofia 2025-06-20  |  Slide 4

With std::constant_wrapper

template<class F> function_ref(F*); template<class F> function_ref(F&&); template<auto f> function_ref(constant_wrapper<f>); template<auto f, class U> function_ref(constant_wrapper<f>, U&&); template<auto f, class T> function_ref(constant_wrapper<f>, T*); template<auto f> function_ref(constant_wrapper<f>) { this->bound-entity = {}; this->thunk-ptr = [](BoundEntityType, Args&&... args) -> R { return constant_wrapper<f>::value (std::forward<Args&&>(args)...); }; }
Jan Schultke  |  Slides for P3740R1 — Last chance to fix std::nontype  |  LEWG at Sofia 2025-06-20  |  Slide 5

Alternatives considered

Jan Schultke  |  Slides for P3740R1 — Last chance to fix std::nontype  |  LEWG at Sofia 2025-06-20  |  Slide 6

std::constant_wrapper concerns

std::cw<&free_function> already behaves much like wrapped function:

constexpr int f() { return 0; } std::move_only_function<int()> r = std::cw<f>; // OK ?!
Jan Schultke  |  Slides for P3740R1 — Last chance to fix std::nontype  |  LEWG at Sofia 2025-06-20  |  Slide 7