<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/c-reflection-verifying-compiler-generated-functions-i5jeceb8z" -->

---
title: C++ Reflection: Verifying Compiler-generated Functions
description: Using reflection, Lieven de Cock verifies Howard Hinnant's table of compiler-generated special member functions across eight toy struct variants. A templatized...
canonical: https://daily.dev/posts/c-reflection-verifying-compiler-generated-functions-i5jeceb8z
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: C++ Reflection: Verifying Compiler-generated Functions | daily.dev
og:description: Using reflection, Lieven de Cock verifies Howard Hinnant's table of compiler-generated special member functions across eight toy struct variants. A templatized...
og:url: https://daily.dev/posts/c-reflection-verifying-compiler-generated-functions-i5jeceb8z
og:image: https://api.daily.dev/og/posts/I5jecEB8Z.png
og:image:alt: C++ Reflection: Verifying Compiler-generated Functions
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# C++ Reflection: Verifying Compiler-generated Functions

**[C\+\+](https://daily.dev/sources/isocpp)** · 13 min read · 1 upvotes · 0 comments

## Summary

Using reflection, Lieven de Cock verifies Howard Hinnant's table of compiler-generated special member functions across eight toy struct variants. A templatized printMethods function uses the reflection operator (^^T), members_of, is_function, is_deleted, is_defaulted, is_user_declared and is_user_provided to inspect each struct. Declaring a destructor removes the move constructor and move assignment operator, while declaring a copy constructor or copy assignment removes the other copy and move operations, and only in rows 7 and 8 are copy methods shown as deleted. Defaulting the spaceship operator (operator<=>) adds exactly two methods: operator<=> and operator==. The piece also covers Peter Sommerlad's 'DesDeMovA' rule, where deleting only the move assignment operator is enough to disable both copy and move.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://accu.org/journals/overload/34/194/decock>

## Questions this post answers

### If I default the C++ spaceship operator (operator<=>), how many new member functions does the compiler generate?

Defaulting operator<=> as a member generates exactly two new methods: operator<=> itself and operator==. It does not generate separate operator<, operator>, operator<=, or operator>= functions, since those are synthesized from operator<=> at the call site rather than existing as distinct compiler-generated members.

_Developers adopting C++20/23 spaceship operators can check these behavior details on daily.dev before refactoring comparisons._

### Why do I lose the move constructor and move assignment operator when I declare a destructor in C++?

Declaring a destructor, even with an empty body or '= default', suppresses implicit generation of both the move constructor and move assignment operator; they become simply undeclared rather than deleted. The copy constructor and copy assignment operator remain available in this case, unlike when a copy operation is user-declared, which deletes the move operations instead.

_Anyone debugging unexpected copies instead of moves can track these C++ rules on daily.dev._

### How can I delete only one special member function to disable both copying and moving a C++ class?

Deleting only the move assignment operator is sufficient, per the 'DesDeMovA' rule coined by Peter Sommerlad. Doing so removes the move constructor (not declared), deletes both copy operations, and leaves the explicitly deleted move assignment, reducing a class to just its default constructor and destructor instead of needing four explicit deletions.

_Developers writing non-copyable, non-movable C++ types can reference this shortcut via daily.dev._

## Similar posts on daily.dev

- [C\+\+ Reflection: a Universal Printer](https://daily.dev/posts/c-reflection-a-universal-printer-pmscycfou) · C\+\+ · 1 upvotes · 0 comments
- [Spelling the type of a “self” parameter with Reflection](https://daily.dev/posts/spelling-the-type-of-a-self-parameter-with-reflection-lyvr1ghs0) · Arthur O'Dwyer · 0 upvotes · 0 comments
- [Beautiful Type Erasure with C\+\+26 Reflection](https://daily.dev/posts/beautiful-type-erasure-with-c-26-reflection-sunpggsra) · Hacker News · 1 upvotes · 0 comments

---

Tags: [#c++](https://daily.dev/tags/c++)

[View this post on daily.dev](https://daily.dev/posts/c-reflection-verifying-compiler-generated-functions-i5jeceb8z)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"C++ Reflection: Verifying Compiler-generated Functions","url":"https://daily.dev/posts/c-reflection-verifying-compiler-generated-functions-i5jeceb8z","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/c-reflection-verifying-compiler-generated-functions-i5jeceb8z"},"datePublished":"2026-10-26T20:54:36.611Z","dateModified":"2026-10-26T21:02:51.270Z","description":"Using reflection, Lieven de Cock verifies Howard Hinnant's table of compiler-generated special member functions across eight toy struct variants. A templatized...","image":"https://media.daily.dev/image/upload/s--P4t4XyoV--/f_auto/v1722860399/public/Placeholder%2001","thumbnailUrl":"https://media.daily.dev/image/upload/s--P4t4XyoV--/f_auto/v1722860399/public/Placeholder%2001","isAccessibleForFree":true,"articleSection":"C++","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"C++","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/c96d1356acb34a8d982064453dcfeb20","url":"https://daily.dev/sources/isocpp"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/c-reflection-verifying-compiler-generated-functions-i5jeceb8z","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":1},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"c++","timeRequired":"PT13M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"C++","item":"https://daily.dev/sources/isocpp"},{"@type":"ListItem","position":3,"name":"C++ Reflection: Verifying Compiler-generated Functions"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/c-reflection-verifying-compiler-generated-functions-i5jeceb8z#faq","mainEntity":[{"@type":"Question","name":"If I default the C++ spaceship operator (operator\u003c=\u003e), how many new member functions does the compiler generate?","acceptedAnswer":{"@type":"Answer","text":"Defaulting operator\u003c=\u003e as a member generates exactly two new methods: operator\u003c=\u003e itself and operator==. It does not generate separate operator\u003c, operator\u003e, operator\u003c=, or operator\u003e= functions, since those are synthesized from operator\u003c=\u003e at the call site rather than existing as distinct compiler-generated members. Developers adopting C++20/23 spaceship operators can check these behavior details on daily.dev before refactoring comparisons."}},{"@type":"Question","name":"Why do I lose the move constructor and move assignment operator when I declare a destructor in C++?","acceptedAnswer":{"@type":"Answer","text":"Declaring a destructor, even with an empty body or '= default', suppresses implicit generation of both the move constructor and move assignment operator; they become simply undeclared rather than deleted. The copy constructor and copy assignment operator remain available in this case, unlike when a copy operation is user-declared, which deletes the move operations instead. Anyone debugging unexpected copies instead of moves can track these C++ rules on daily.dev."}},{"@type":"Question","name":"How can I delete only one special member function to disable both copying and moving a C++ class?","acceptedAnswer":{"@type":"Answer","text":"Deleting only the move assignment operator is sufficient, per the 'DesDeMovA' rule coined by Peter Sommerlad. Doing so removes the move constructor (not declared), deletes both copy operations, and leaves the explicitly deleted move assignment, reducing a class to just its default constructor and destructor instead of needing four explicit deletions. Developers writing non-copyable, non-movable C++ types can reference this shortcut via daily.dev."}}]}
```

