Slides for P3740R0
Last chance to fix std::nontype

Document number:
P3753R0
Date:
2025-06-17
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
P3740R0

Jan Schultke  |  Slides for P3740R0 — Last chance to fix std::nontype  |  SG22 Telecon 2025-16-06  |  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 P3740R0 — Last chance to fix std::nontype  |  SG22 Telecon 2025-16-06  |  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 and noex for now.

Jan Schultke  |  Slides for P3740R0 — Last chance to fix std::nontype  |  SG22 Telecon 2025-16-06  |  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 P3740R0 — Last chance to fix std::nontype  |  SG22 Telecon 2025-16-06  |  Slide 4

Proposed alternative: std::stateless

template<class F> function_ref(F*); template<class F> function_ref(F&&); template<class F> function_ref(stateless_t, const F&); template<class F, class U> function_ref(stateless_t, const F&, U&&); template<class F, class T> function_ref(stateless_t, const F&, T*); template<class F, class T> function_ref(stateless_t, const F&) { this->bound-entity = {}; this->thunk-ptr = [](BoundEntityType, Args&&... args) -> R { return F{}(std::forward<Args&&>(args)...); }; }
Jan Schultke  |  Slides for P3740R0 — Last chance to fix std::nontype  |  SG22 Telecon 2025-16-06  |  Slide 5

Alternatives considered

Jan Schultke  |  Slides for P3740R0 — Last chance to fix std::nontype  |  SG22 Telecon 2025-16-06  |  Slide 6

Why not just use std::constant_wrapper

std::constant_wrapper<int(*)()> already behaves much like the function pointer it wraps. Therefore:

Jan Schultke  |  Slides for P3740R0 — Last chance to fix std::nontype  |  SG22 Telecon 2025-16-06  |  Slide 7

Most viable solutions

Jan Schultke  |  Slides for P3740R0 — Last chance to fix std::nontype  |  SG22 Telecon 2025-16-06  |  Slide 8