Skip to content

Instantly share code, notes, and snippets.

@GerHobbelt
Forked from beached/C++ normal operators.md
Last active February 1, 2026 18:49
Show Gist options
  • Select an option

  • Save GerHobbelt/eecacd54a086232745780981a9787d99 to your computer and use it in GitHub Desktop.

Select an option

Save GerHobbelt/eecacd54a086232745780981a9787d99 to your computer and use it in GitHub Desktop.
A list of the normal signatures of C++ operators that allow overloading

C++ Operator Signatures

This is a list of C++ operators that can be overloaded and their normal signatures (a.k.a what an int would do). The order is the prefered order to use them. (The first one listed is often prefered.)

Arithmetic

operator+ addition

  • free function -> T operator+( T const & lhs, T const & rhs )
  • member function -> T operator+( T const & rhs ) const

operator+ unary plus

  • member function -> T operator+( ) const
  • free function -> T & operator+( T const & value )

operator+= addition assignment

  • member function -> T & operator+=( T const & rhs )
  • free function -> T & operator+=( T & lhs, T const & rhs )

operator++ increment

  • member function -> T & operator++( ) -> prefix ++T
  • member function -> T operator++( int ) -> postfix T++
  • free function -> T & operator++( T & value ) -> prefix ++T
  • free function -> T operator++( T & value, int ) -> postfix T++

operator- subtraction

  • free function -> T operator-( T const & lhs, T const & rhs )
  • member function -> T operator-( T const & rhs ) const

opeator- unary negation

  • member function -> T operator-( ) const
  • free function -> T operator-( T const & value )

operator-= subtraction assignment

  • free function -> T & operator-=( T & lhs, T const & rhs )
  • member function -> T & operator-=( T const & rhs )

operator-- decrement

  • member function -> T & operator--( ) -> prefix --T
  • member function -> T operator--( int ) -> postfix T--
  • free function -> T & operator--( T & value ) -> prefix --T
  • free function -> T operator--( T & value, int ) -> postfix T--

operator* multiplication

  • free function -> T operator*( T const & lhs, T const & rhs )
  • member function -> T operator*( T const & rhs ) const

operator*= multiplication assignment

  • free function -> T & operator*=( T & lhs, T const & rhs )
  • member function -> T & operator*=( T const & rhs )

operator/ division

  • free function -> T operator/( T const & lhs, T const & rhs )
  • member function -> T operator/( T const & rhs ) const

operator/= division assignment

  • free function -> T & operator/=( T & lhs, T const & rhs )
  • member function -> T & operator/=( T const & rhs )

operator% modulus/remainder

  • free function -> T operator%( T const & lhs, T const & rhs )
  • member function -> T operator%( T const & rhs ) const

operator%= modulus/remainder assignment

  • free function -> T & operator%=( T & lhs, T const & rhs )
  • member function -> T & operator%=( T const & rhs )

Bitwise

operator<< left shift

  • free function -> T operator<<( T const & lhs, size_t pos )
  • member function -> T operator<<( size_t pos ) const

operator<<= left shift assignment

  • free function -> T & operator<<=( T & lhs, size_t pos )
  • member function -> T & operator<<=( size_t pos )

operator>> right shift

  • free function -> T operator>>( T const & lhs, size_t pos )
  • member function -> T operator<<( size_t pos ) const

operator>>= right shift assignment

  • free function -> T & operator>>=( T & lhs, size_t pos )
  • member function -> T & operator<<=( size_t pos )

operator| or operator bitor bitwise or

  • free function -> T operator|( T const & lhs, T const & rhs )
  • member function -> T operator|( T const & rhs ) const

operator|= or operator or_eq bitwise or assignment

  • free function -> T & operator|=( T & lhs, T const & rhs )
  • member function -> T & operator|=( T const & rhs )

operator& or operator bitand bitwise and

  • free function -> T operator&( T const & lhs, T const & rhs )
  • member function -> T operator&( T const & rhs ) const

operator&= or operator and_eq bitwise and assignment

  • free function -> T & operator&=( T & lhs, T const & rhs )
  • member function -> T & operator&=( T const & rhs )

operator^ or operator xor bitwise xor

  • free function -> T operator^( T const & lhs, T const & rhs )
  • member function -> T operator^( T const & rhs ) const

operator^= or operator xor_eq bitwise xor assignment

  • member function -> T & operator^=( T const & rhs )
  • free function -> T & operator^=( T & lhs, T const & rhs )

operator~ one's compliment or bitwise not

  • member function -> T operator~( ) const
  • free function -> T operator~( T const & value )

Logical

operator== equality

  • free function -> bool operator==( T const & lhs, T const & rhs )
  • member function -> bool operator==( T const & rhs ) const

operator!= or operator not_eq inequality

  • free function -> bool operator!=( T const & lhs, T const & rhs )
  • member function -> bool operator!=( T const & rhs ) const

operator< less than

  • free function -> bool operator<( T const & lhs, T const & rhs )
  • member function -> bool operator<( T const & rhs ) const

operator<= less than or equal

  • free function -> bool operator<=( T const & lhs, T const & rhs )
  • member function -> bool operator<=( T const & rhs ) const

operator> greater than

  • free function -> bool operator>( T const & lhs, T const & rhs )
  • member function -> bool operator>( T const & rhs )

operator>= greater than or equal

  • free function -> bool operator>=( T const & lhs, T const & rhs )
  • member function -> bool operator>=( T const & rhs ) const

operator&& or operator and logical and

  • free function -> bool operator&&( T const & lhs, T const & rhs )
  • member function -> bool operator&&( T const & rhs ) const

operator|| or operator or logical or

  • free function -> bool operator||( T const & lhs, T const & rhs )
  • member function -> bool operator||( T const & rhs ) const

operator! or operator not logical not

  • member function -> bool operator!( ) const
  • free function -> bool operator!( T const & value ) const

operator<=> spaceship operator

Other

operator-> member access

  • member function -> T * operator->( )
  • member function -> T const * operator->( ) const also T * is normal

operator* dereference

  • member function -> T & operator*( )
  • member function -> T const & operator*( ) const

operator[] subscript

  • member function -> T & operator[]( size_t pos )> pos can be any single argument type
  • member function -> T const & operator[]( size_t pos ) const> pos can be any single argument type

operator->*

  • free function -> Anything operator->( Anything lhs, Anything rhs )

operator( ) function

  • member function -> Anything operator( )( Anything... args )

operator, comma

  • Please don't :)
  • member function -> Anything operator,( Anything )
  • free function -> Anything operator,( Anything lhs, Anything rhs )

operator& address of

  • Please don't :)
  • member function -> T * operator&( )
  • member function -> T const * operator&( ) const or T*

operator( ) cast

  • member function -> From a type T -> operator U( ) const

operator<< stream insertion

  • free function -> std::ostream & operator<<( std::ostream & os, T const & value )

operator>> stream extraction

  • free function -> std::istream & operator>>( std::istream & is, T & value )

operator new or operator new[]

operator delete or operator delete[]

operator ""_Suffix a.k.a. user-defined literals

Compiler: clang v21.1.0 (https://github.com/llvm/llvm-project.git 3623fe661ae35c6c80ac221f14d85be76aa870f1)
Language: C++ v202002
C++ language version: C++20
+ operator <=> (spaceship) supported? --> YES
std::format supported? -----------------> YES
---------------------------------------
--> T(11) / (constructor)
--> T(21) / (constructor)
--> T(31) / (constructor)
--> T(41) / (constructor)
--> T(51) / (constructor)
--> T(61) / (constructor)
--> T(71) / (constructor)
--> T(81) / (constructor)
--> T(91) / (constructor)
11/21 / 71/81
--> operator==(11) / rhs:(21)
true --> operator!=(11) / rhs:(21)
false --> operator<(11) / rhs:(21)
false --> operator<=(11) / rhs:(21)
true --> operator>(11) / rhs:(21)
false --> operator>=(11) / rhs:(21)
true --> operator<=>(11) / rhs:(21)
equal
---------------------------------------
---------------------------------------
____________-- expression: t1 + t2
--> operator+(11) / rhs:(21)
--> T(102) / (constructor)
resulting value: 0 --> operator<<(102) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 + t2
---------------------------------------
--> ~T(102)
---------------------------------------
____________-- expression: t1 - t2
--> operator-(11) / rhs:(21)
--> T(113) / (copy constructor)
resulting value: 0 --> operator<<(113) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 - t2
---------------------------------------
--> ~T(113)
---------------------------------------
____________-- expression: t1 * t2
--> operator*(11) / rhs:(21)
--> T(122) / (constructor)
resulting value: 0 --> operator<<(122) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 * t2
---------------------------------------
--> ~T(122)
---------------------------------------
____________-- expression: t1 / t2
--> operator/(11) / rhs:(21)
--> T(132) / (constructor)
resulting value: 0 --> operator<<(132) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 / t2
---------------------------------------
--> ~T(132)
---------------------------------------
____________-- expression: t1 % t2
--> operator%(11) / rhs:(21)
--> T(142) / (constructor)
resulting value: 0 --> operator<<(142) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 % t2
---------------------------------------
--> ~T(142)
---------------------------------------
____________-- expression: t1 ^ t2
--> operator^(11) / rhs:(21)
--> T(152) / (constructor)
resulting value: 0 --> operator<<(152) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 ^ t2
---------------------------------------
--> ~T(152)
---------------------------------------
____________-- expression: t1 & t2
--> operator&(11) / rhs:(21)
--> T(162) / (constructor)
resulting value: 0 --> operator<<(162) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 & t2
---------------------------------------
--> ~T(162)
---------------------------------------
____________-- expression: t1 | t2
--> operator|(11) / rhs:(21)
--> T(172) / (constructor)
resulting value: 0 --> operator<<(172) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 | t2
---------------------------------------
--> ~T(172)
---------------------------------------
____________-- expression: ~t1
--> operator~(11)
--> T(182) / (constructor)
resulting value: 0 --> operator<<(182) / (ostream insertion)
^^^^^^^^^^^^-- output for: ~t1
---------------------------------------
--> ~T(182)
---------------------------------------
____________-- expression: !t1
--> operator!(11)
resulting value: false
^^^^^^^^^^^^-- output for: !t1
---------------------------------------
---------------------------------------
____________-- expression: t1 < t2
--> operator<(11) / rhs:(21)
resulting value: false
^^^^^^^^^^^^-- output for: t1 < t2
---------------------------------------
---------------------------------------
____________-- expression: t1 <= t2
--> operator<=(11) / rhs:(21)
resulting value: true
^^^^^^^^^^^^-- output for: t1 <= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 == t2
--> operator==(11) / rhs:(21)
resulting value: true
^^^^^^^^^^^^-- output for: t1 == t2
---------------------------------------
---------------------------------------
____________-- expression: t1 != t2
--> operator!=(11) / rhs:(21)
resulting value: false
^^^^^^^^^^^^-- output for: t1 != t2
---------------------------------------
---------------------------------------
____________-- expression: t1 >= t2
--> operator>=(11) / rhs:(21)
resulting value: true
^^^^^^^^^^^^-- output for: t1 >= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 > t2
--> operator>(11) / rhs:(21)
resulting value: false
^^^^^^^^^^^^-- output for: t1 > t2
---------------------------------------
---------------------------------------
____________-- expression: ordering_as_string(t1 <=> t2)
--> operator<=>(11) / rhs:(21)
resulting value: equal
^^^^^^^^^^^^-- output for: ordering_as_string(t1 <=> t2)
---------------------------------------
---------------------------------------
____________-- expression: t1 += t2
--> operator+=(11) / rhs:(21)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 += t2
---------------------------------------
---------------------------------------
____________-- expression: t1 -= t2
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 -= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 *= t2
--> operator*=(11) / rhs:(21)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 *= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 /= t2
--> operator/=(11) / rhs:(21)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 /= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 %= t2
--> operator%=(11) / rhs:(21)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 %= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 ^= t2
--> operator^=(11) / rhs:(21)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 ^= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 &= t2
--> operator&=(11) / rhs:(21)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 &= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 |= t2
--> operator|=(11) / rhs:(21)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 |= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 << t2
--> operator unsigned long(21)
--> operator<<(11) / offset:0
--> T(192) / (constructor)
resulting value: 0 --> operator<<(192) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 << t2
---------------------------------------
--> ~T(192)
---------------------------------------
____________-- expression: t1 >> t2
--> operator unsigned long(21)
--> operator>>(11) / offset:0
--> T(202) / (constructor)
resulting value: 0 --> operator<<(202) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 >> t2
---------------------------------------
--> ~T(202)
---------------------------------------
____________-- expression: t1 <<= t2
--> operator unsigned long(21)
--> operator<<=(11) / offset:0
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 <<= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 >>= t2
--> operator unsigned long(21)
--> operator>>=(11) / offset:0
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 >>= t2
---------------------------------------
---------------------------------------
____________-- expression: t1++
--> operator++(11) / (postfix ++)
--> T(213) / (copy constructor)
resulting value: 0 --> operator<<(213) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1++
---------------------------------------
--> ~T(213)
---------------------------------------
____________-- expression: ++t1
--> operator++(11) / (prefix ++)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: ++t1
---------------------------------------
---------------------------------------
____________-- expression: t1--
--> operator--(11) / (postfix --)
--> T(223) / (copy constructor)
resulting value: 0 --> operator<<(223) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1--
---------------------------------------
--> ~T(223)
---------------------------------------
____________-- expression: --t1
--> operator--(11) / (prefix --)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: --t1
---------------------------------------
---------------------------------------
____________-- expression: t1 && t2 && t3 && t4 && t5 && t6
--> operator&&(11) / rhs:(21)
--> operator&&(---) / (special EXTRA bool && T overload) / rhs:(31)
--> operator&&(---) / (special EXTRA bool && T overload) / rhs:(41)
--> operator&&(---) / (special EXTRA bool && T overload) / rhs:(51)
--> operator&&(---) / (special EXTRA bool && T overload) / rhs:(61)
resulting value: false
^^^^^^^^^^^^-- output for: t1 && t2 && t3 && t4 && t5 && t6
---------------------------------------
---------------------------------------
____________-- expression: t1 || t2 || t3 || t4 || t5 || t6
--> operator||(11) / rhs:(21)
--> operator||(---) / (special EXTRA bool && T overload) / rhs:(31)
--> operator||(---) / (special EXTRA bool && T overload) / rhs:(41)
--> operator||(---) / (special EXTRA bool && T overload) / rhs:(51)
--> operator||(---) / (special EXTRA bool && T overload) / rhs:(61)
resulting value: true
^^^^^^^^^^^^-- output for: t1 || t2 || t3 || t4 || t5 || t6
---------------------------------------
---------------------------------------
____________-- expression: t1[0]
--> operator[](11) / pos:0
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1[0]
---------------------------------------
---------------------------------------
____________-- expression: t1(1)
--> operator()(11) / arg1:1
resulting value: 0
^^^^^^^^^^^^-- output for: t1(1)
---------------------------------------
---------------------------------------
____________-- expression: t1->a
--> operator->(11)
resulting value: 0
^^^^^^^^^^^^-- output for: t1->a
---------------------------------------
---------------------------------------
____________-- expression: &t1
--> operator&(11)
resulting value: 0x7ffc31795584
^^^^^^^^^^^^-- output for: &t1
---------------------------------------
---------------------------------------
____________-- expression: (t1, t2)
--> operator int(21)
--> operator,(11)
--> T(233) / (copy constructor)
resulting value: 0 --> operator<<(233) / (ostream insertion)
^^^^^^^^^^^^-- output for: (t1, t2)
---------------------------------------
--> ~T(233)
---------------------------------------
____________-- expression: long(t1)
--> operator long(11)
resulting value: 0
^^^^^^^^^^^^-- output for: long(t1)
---------------------------------------
---------------------------------------
____________-- expression: t3 = t1
--> operator=(31) / rhs:(11)
--> T(243) / (copy constructor)
resulting value: 0 --> operator<<(243) / (ostream insertion)
^^^^^^^^^^^^-- output for: t3 = t1
---------------------------------------
--> ~T(243)
--> ~T(91)
--> ~T(81)
--> ~T(71)
--> ~T(61)
--> ~T(51)
--> ~T(41)
--> ~T(31)
--> ~T(21)
--> ~T(11)
Done!
// MSVC: /std:c++20 /Zc:__cplusplus /Zc:preprocessor (without the /Zc the language version reporting + macro work will fail!)
// clang: -std=c++20
// gcc: -std=c++20
//
// The code below uses compile-time feature detect preprocessor code to assist:
// the code SHOULD compile with older C++ language version settings; this assertion has only been tested intermittantly
// with GCC/clang/MSVC at godbolt, so YMMV for your C++17 and older.
//
// https://godbolt.org/z/67Wehevah
//
#include <initializer_list>
#include <string>
#include <iostream>
#include <cstdarg>
#include <cassert>
// features:
#define EXTRA_OVERLOADS 1 // see further below for comment block which mentions this one. That's a hint. ;-)
#if defined(_MSC_VER) && !defined(__has_include)
#define __has_include(arg) 0
#endif
#if __has_include(<format>)
# include <format>
// clang still b0rks with: error: no member named 'format' in namespace 'std' -- when the CLI options don't include std c++20 at least!
// The include file check above is not sufficient as clang will always have libstdc++'s format header file available...
# if __cplusplus >= 202002L
# define STD_FORMAT_IS_SUPPORTED 1
# endif
#endif
// https://stackoverflow.com/questions/65472035/checking-for-three-way-comparison-operator-support-at-compile-time
#if __has_include(<compare>)
# include <compare>
# if defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907
# define SPACESHIP_OPERATOR_IS_SUPPORTED 1
# endif
#endif
static int object_numero_ctr = 1;
// instances of struct T have ids that increment per decade, i.e. 10,20,30,...
// while the unit digit identifies the actual constructor used to instantiate that particular object instance, ergo, f.e. 13, 21, 31, ...
static int mk_id(int preproc__counter__) {
return (object_numero_ctr++) * 10 + preproc__counter__ + 1; // __COUNTER__ starts at 0 and we wish to start at 1 per object: unit digit identifies the actual constructor used: see below in the `struct T` definition.
}
static const char *currently_tested_expression = nullptr;
#define TRACE_ARGS_1(_1) /**/
#define TRACE_ARGS_2(_1, _2) TRACE_ARGS_1(_1) << " / " << _2
#define TRACE_ARGS_3(_1, _2, _3) TRACE_ARGS_1(_1) << " / " << _2 << " / " << _3
#define TRACE_ARGS_4(_1, _2, _3, _4) TRACE_ARGS_1(_1) << " / " << _2 << " / " << _3 << " / " << _4
#define TRACE_ARGS_OVERRIDE(_1, _2, _3, _4, NAME, ...) NAME
#define TRACE_ARG(...) TRACE_ARGS_OVERRIDE(__VA_ARGS__, TRACE_ARGS_4, TRACE_ARGS_3, TRACE_ARGS_2, TRACE_ARGS_1)(__VA_ARGS__)
#define TRACE_THIS_ID() this->id
#ifdef STD_FORMAT_IS_SUPPORTED
#define TRACE(...) std::cout << std::format(" --> {}({})", __func__, TRACE_THIS_ID()) TRACE_ARG("" __VA_OPT__(,) __VA_ARGS__) << "\n"
#else
#define TRACE(...) std::cout << " --> " << __func__ << "(" << TRACE_THIS_ID() << ")" << /* TRACE_ARG("" __VA_OPT__(,) __VA_ARGS__) << */ "\n"
#endif
static void report_cpp_language_version(void) {
std::cout << "C++ v" << __cplusplus << "\nC++ language version: ";
if (__cplusplus == 202302L) std::cout << "C++23";
else if (__cplusplus == 202002L) std::cout << "C++20";
else if (__cplusplus == 201703L) std::cout << "C++17";
else if (__cplusplus == 201402L) std::cout << "C++14";
else if (__cplusplus == 201103L) std::cout << "C++11";
else if (__cplusplus == 199711L) std::cout << "C++98";
else std::cout << "pre-standard C++." << __cplusplus;
std::cout << "\n";
}
static void report_compiler_version(void) {
#if defined(_MSC_VER)
std::cout << "Microsoft CL v" << _MSC_VER << " (full: v" << _MSC_FULL_VER << ")";
#elif defined(__clang__)
std::cout << "clang v" << __clang_version__;
#elif defined(__GNUC__)
std::cout << "gcc v" << __GNUC__ << "." << __GNUC_MINOR__ << " (v" << __VERSION__ << ")";
#elif defined(__VERSION__)
std::cout << "??? v" << __VERSION__;
#else
std::cout << "???";
#endif
std::cout << "\n";
}
template <class M>
struct T {
int id;
M a, b;
// constructors & destructor
T()
: a{}, b{}, id(mk_id(__COUNTER__)) {
TRACE("(constructor)");
}
~T() {
TRACE();
}
T(M v1, M v2)
: a{v1}, b{v2}, id(mk_id(__COUNTER__)) {
TRACE("(constructor)");
}
// copy constructor
T(const T &v)
: a{v.a}, b{v.b}, id(mk_id(__COUNTER__)) {
TRACE("(copy constructor)");
}
// move constructor
T(T &&v) noexcept
: a{std::move(v.a)}, b{std::move(v.b)}, id(mk_id(__COUNTER__)) {
TRACE("(move constructor)", std::format("v:({})", v.id) );
}
// ---------------------------------------------------------
// a list of C++ operators that can be overloaded
//
// any of the following operators: + - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= <=>(since C++20) && || ++ -- , ->* -> () []
// assignment operator
T operator =(const T &rhs) {
TRACE(std::format("rhs:({})", rhs.id));
a = rhs.a;
b = rhs.b;
return *this;
}
T operator =(T &&rhs) {
TRACE(std::format("rhs:({})", rhs.id));
a = std::move(rhs.a);
b = std::move(rhs.b);
return *this;
}
// Arithmetic:
// operator+ addition
T operator+(T const & rhs) const {
TRACE(std::format("rhs:({})", rhs.id));
return {a, b};
}
// free function -> T operator+(T const & lhs, T const & rhs)
// operator+ unary plus
T operator+() const {
TRACE("(unary +)");
auto v = a + 1;
return v;
}
// free function -> T & operator+(T const & value)
// operator+= addition assignment
T & operator+=(T const & rhs) {
TRACE(std::format("rhs:({})", rhs.id));
return *this;
}
// free function -> T & operator+=(T & lhs, T const & rhs)
// operator++ increment
// prefix ++T
T & operator++() {
TRACE("(prefix ++)");
return *this;
}
// postfix T++
T operator++(int) {
TRACE("(postfix ++)");
return *this;
}
// free function -> T & operator++(T & value) -> prefix ++T
// free function -> T operator++(T & value, int) -> postfix T++
// operator- subtraction
T operator-(T const & rhs) const {
TRACE(std::format("rhs:({})", rhs.id));
return *this;
}
// free function -> T operator-(T const & lhs, T const & rhs)
// opeator- unary negation
T operator-() const {
TRACE("(unary minus)");
return *this;
}
// free function -> T operator-(T const & value)
// operator-= subtraction assignment
T & operator-=(T const & rhs) {
return *this;
}
// free function -> T & operator-=(T & lhs, T const & rhs)
// operator-- decrement
// prefix --T
T & operator--() {
TRACE("(prefix --)");
return *this;
}
// postfix T--
T operator--(int) {
TRACE("(postfix --)");
return *this;
}
// free function -> T & operator--(T & value) -> prefix --T
// free function -> T operator--(T & value, int) -> postfix T--
// operator* multiplication
T operator*(T const & rhs) const {
TRACE(std::format("rhs:({})", rhs.id));
return {a, b};
}
// free function -> T operator*(T const & lhs, T const & rhs)
// operator*= multiplication assignment
T & operator*=(T const & rhs) {
TRACE(std::format("rhs:({})", rhs.id));
return *this;
}
// free function -> T & operator*=(T & lhs, T const & rhs)
// operator/ division
T operator/(T const & rhs) const {
TRACE(std::format("rhs:({})", rhs.id));
return {a, b};
}
// free function -> T operator/(T const & lhs, T const & rhs)
// operator/= division assignment
T & operator/=(T const & rhs) {
TRACE(std::format("rhs:({})", rhs.id));
return *this;
}
// free function -> T & operator/=(T & lhs, T const & rhs)
// operator% modulus/remainder
T operator%(T const & rhs) const {
TRACE(std::format("rhs:({})", rhs.id));
return {a, b};
}
// free function -> T operator%(T const & lhs, T const & rhs)
// operator%= modulus/remainder assignment
T & operator%=(T const & rhs) {
TRACE(std::format("rhs:({})", rhs.id));
return *this;
}
// free function -> T & operator%=(T & lhs, T const & rhs)
// Bitwise
// operator<< left shift
T operator<<(size_t pos) const {
TRACE(std::format("offset:{}", pos));
return {a, b};
}
// free function -> T operator<<(T const & lhs, size_t pos)
// operator<<= left shift assignment
T & operator<<=(size_t pos) {
TRACE(std::format("offset:{}", pos));
return *this;
}
// free function -> T & operator<<=(T & lhs, size_t pos)
// operator>> right shift
T operator>>(size_t pos) const {
TRACE(std::format("offset:{}", pos));
return {a, b};
}
// free function -> T operator>>(T const & lhs, size_t pos)
// operator>>= right shift assignment
T & operator>>=(size_t pos) {
TRACE(std::format("offset:{}", pos));
return *this;
}
// free function -> T & operator>>=(T & lhs, size_t pos)
// operator| or operator bitor bitwise or
T operator|(T const & rhs) const {
TRACE(std::format("rhs:({})", rhs.id));
return {a, b};
}
// free function -> T operator|(T const & lhs, T const & rhs)
// operator|= or operator or_eq bitwise or assignment
T & operator|=(T const & rhs) {
TRACE(std::format("rhs:({})", rhs.id));
return *this;
}
// free function -> T & operator|=(T & lhs, T const & rhs)
// operator& or operator bitand bitwise and
T operator&(T const & rhs) const {
TRACE(std::format("rhs:({})", rhs.id));
return {a, b};
}
// free function -> T operator&(T const & lhs, T const & rhs)
// operator&= or operator and_eq bitwise and assignment
T & operator&=(T const & rhs) {
TRACE(std::format("rhs:({})", rhs.id));
return *this;
}
// free function -> T & operator&=(T & lhs, T const & rhs)
// operator^ or operator xor bitwise xor
T operator^(T const & rhs) const {
TRACE(std::format("rhs:({})", rhs.id));
return {a, b};
}
// free function -> T operator^(T const & lhs, T const & rhs)
// operator^= or operator xor_eq bitwise xor assignment
T & operator^=(T const & rhs) {
TRACE(std::format("rhs:({})", rhs.id));
return *this;
}
// free function -> T & operator^=(T & lhs, T const & rhs)
// operator~ one's compliment or bitwise not
T operator~() const {
TRACE();
return {a, b};
}
// free function -> T operator~(T const & value)
// Logical
// operator== equality
bool operator==(T const & rhs) const {
TRACE(std::format("rhs:({})", rhs.id));
return a == rhs.a;
}
// free function -> bool operator==(T const & lhs, T const & rhs)
// operator!= or operator not_eq inequality
bool operator!=(T const & rhs) const {
TRACE(std::format("rhs:({})", rhs.id));
return a != rhs.a;
}
// free function -> bool operator!=(T const & lhs, T const & rhs)
// operator< less than
bool operator<(T const & rhs) const {
TRACE(std::format("rhs:({})", rhs.id));
return a < rhs.a;
}
// free function -> bool operator<(T const & lhs, T const & rhs)
// operator<= less than or equal
bool operator<=(T const & rhs) const {
TRACE(std::format("rhs:({})", rhs.id));
return a <= rhs.a;
}
// free function -> bool operator<=(T const & lhs, T const & rhs)
// operator> greater than
bool operator>(T const & rhs) {
TRACE(std::format("rhs:({})", rhs.id));
return a > rhs.a;
}
// free function -> bool operator>(T const & lhs, T const & rhs)
// operator>= greater than or equal
bool operator>=(T const & rhs) const {
TRACE(std::format("rhs:({})", rhs.id));
return a >= rhs.a;
}
// free function -> bool operator>=(T const & lhs, T const & rhs)
// operator&& or operator and logical and
bool operator&&(T const & rhs) const {
TRACE(std::format("rhs:({})", rhs.id));
return false; // despite this result, there won't be any 'shortcircuit evaluation'!
}
// free function -> bool operator&&(T const & lhs, T const & rhs)
// operator|| or operator or logical or
bool operator||(T const & rhs) const {
TRACE(std::format("rhs:({})", rhs.id));
return true; // despite this result, there won't be any 'shortcircuit evaluation'!
}
// free function -> bool operator||(T const & lhs, T const & rhs)
// operator! or operator not logical not
bool operator!() const {
TRACE();
return false;
}
// free function -> bool operator!(T const & value) const
#ifdef SPACESHIP_OPERATOR_IS_SUPPORTED
// operator<=> spaceship operator
// See[p0515 paper](https://wg21.link/p0515r3)
[[nodiscard]] std::strong_ordering operator<=>(const T& rhs) const {
TRACE(std::format("rhs:({})", rhs.id));
#if 01
if (a == b)
return std::strong_ordering::equivalent;
if (a < b)
return std::strong_ordering::less;
//if (b < a)
return std::strong_ordering::greater;
#else
if (a == b)
return std::partial_ordering::equivalent;
if (a < b)
return std::partial_ordering::less;
if (b < a)
return std::partial_ordering::greater;
return std::partial_ordering::unordered;
#endif
}
// implicitly declares: [[nodiscard]] bool operator==(const T&) const;
#endif
// Other
// operator-> member access
T * operator->() {
TRACE();
return this;
}
// member function -> T const * operator->() const also T * is normal
// operator* dereference
T & operator*() {
TRACE();
return *this;
}
// member function -> T const & operator*() const
//
// Feature-test macro Value Std Feature
// __cpp_static_call_operator 202207L (C++23) static operator()
// __cpp_multidimensional_subscript 202211L (C++23) static operator[]
//
// operator[] subscript
// pos can be any single argument type
T & operator[](size_t pos) {
TRACE(std::format("pos:{}", pos));
if (pos == 0)
return *this;
else
return *this;
}
// pos can be any single argument type
T const & operator[](size_t pos) const {
TRACE(std::format("pos:{}", pos));
if (pos == 0)
return *this;
else
return *this;
}
// operator->*
// free function -> Anything operator->(Anything lhs, Anything rhs)
// operator() function
M operator()(M arg) {
TRACE(std::format("arg1:{}", arg));
return a;
}
// operator, comma -- Please don't :)
T operator,(M x) {
TRACE();
return *this;
}
// free function -> Anything operator,(Anything lhs, Anything rhs)
// operator& address of -- Please don't :)
T * operator&() {
TRACE();
return this;
}
// member function -> T const * operator&() const or T*
// operator( ) cast
template<class U>
operator U() const {
TRACE();
return static_cast<U>(a);
}
// operator<< stream insertion
// free function -> std::ostream & operator<<(std::ostream & os, T const & value)
// operator>> stream extraction
// free function -> std::istream & operator>>(std::istream & is, T & value)
// operator new or operator new[]
// See[cppreference.com operator new](https://en.cppreference.com/w/cpp/memory/new/operator_new)
// operator delete or operator delete[]
// See[cppreference.com operator delete](https://en.cppreference.com/w/cpp/memory/new/operator_delete)
#undef TRACE_THIS_ID
#define TRACE_THIS_ID() value.id
// operator<< stream insertion
friend std::ostream & operator<<(std::ostream & os, T const & value) {
os << value.a;
TRACE("(ostream insertion)");
return os;
}
// operator>> stream extraction
friend std::istream & operator>>(std::istream & is, T & value) {
TRACE("(istream extraction)");
value.a = {};
return is;
}
#ifdef EXTRA_OVERLOADS
#undef TRACE_THIS_ID
#define TRACE_THIS_ID() "---"
// operator&& or operator and logical and
friend bool operator&&(bool lhs, T const & rhs) {
TRACE("(special EXTRA bool && T overload)", std::format("rhs:({})", rhs.id));
return false; // despite this result, there won't be any 'shortcircuit evaluation'!
}
// operator|| or operator or logical or
friend bool operator||(bool lhs, T const & rhs) {
TRACE("(special EXTRA bool && T overload)", std::format("rhs:({})", rhs.id));
return true; // despite this result, there won't be any 'shortcircuit evaluation'!
}
#endif
};
#ifdef SPACESHIP_OPERATOR_IS_SUPPORTED
static std::string ordering_as_string(const std::strong_ordering o) {
if (o == std::strong_ordering::less)
return "less";
if (o == std::strong_ordering::equal)
return "equal";
if (o == std::strong_ordering::equivalent)
return "equivalent";
if (o == std::strong_ordering::greater)
return "greater";
return "???";
}
#endif
static void report_start_of_test(const char *operation) {
currently_tested_expression = operation;
std::cout << "\n---------------------------------------\n";
std::cout << "____________-- expression: " << operation << "\n\n";
}
template <class T>
static void ignore_unused(const T &v, const char *operation) {
(void)(v);
std::cout << "\nresulting value: " << v;
std::cout << "\n^^^^^^^^^^^^-- output for: " << operation;
std::cout << "\n---------------------------------------\n\n";
currently_tested_expression = nullptr;
}
#define ignore_unused(arg) report_start_of_test(#arg); ignore_unused(arg, #arg);
static void T_demo(void) {
T<int> t1, t2, t3, t4, t5, t6;
T<std::string> s1, s2, s3;
#ifdef STD_FORMAT_IS_SUPPORTED
std::cout << std::format("{}/{} / {}/{}", t1.id, t2.id, s1.id, s2.id);
#else
std::cout << t1.id << "/" << t2.id << " / " << s1.id << "/" << s2.id;
#endif
std::cout
<< '\n'
<< std::boolalpha
<< (t1 == t2) << ' '
<< (t1 != t2) << ' '
<< (t1 < t2) << ' '
<< (t1 <= t2) << ' '
<< (t1 > t2) << ' '
<< (t1 >= t2) << ' '
#ifdef SPACESHIP_OPERATOR_IS_SUPPORTED
<< ordering_as_string(t1 <=> t2)
#endif
<< '\n';
std::cout << "---------------------------------------\n\n";
// any of the following operators: + - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= <=>(since C++20) && || ++ -- , ->* -> () []
ignore_unused(t1 + t2);
ignore_unused(t1 - t2);
ignore_unused(t1 * t2);
ignore_unused(t1 / t2);
ignore_unused(t1 % t2);
ignore_unused(t1 ^ t2);
ignore_unused(t1 & t2);
ignore_unused(t1 | t2);
ignore_unused(~t1);
ignore_unused(!t1);
ignore_unused(t1 < t2);
ignore_unused(t1 <= t2);
ignore_unused(t1 == t2);
ignore_unused(t1 != t2);
ignore_unused(t1 >= t2);
ignore_unused(t1 > t2);
#ifdef SPACESHIP_OPERATOR_IS_SUPPORTED
ignore_unused(ordering_as_string(t1 <=> t2));
#endif
ignore_unused(t1 += t2);
ignore_unused(t1 -= t2);
ignore_unused(t1 *= t2);
ignore_unused(t1 /= t2);
ignore_unused(t1 %= t2);
ignore_unused(t1 ^= t2);
ignore_unused(t1 &= t2);
ignore_unused(t1 |= t2);
ignore_unused(t1 << t2);
ignore_unused(t1 >> t2);
ignore_unused(t1 <<= t2);
ignore_unused(t1 >>= t2);
ignore_unused(t1++);
ignore_unused(++t1);
ignore_unused(t1--);
ignore_unused(--t1);
ignore_unused(t1 && t2 && t3 && t4 && t5 && t6);
ignore_unused(t1 || t2 || t3 || t4 || t5 || t6);
// while the `operator &&` overload documentation says you LOOSE the 'shortcircuit boolean evaluation' of these operators,
// our test output will APPARENTLY show a different reality: only the first `t1 && t2` is invoked, and ditto for the `||`
// so that SOUNDS like shortcircuit evaluation, doesn't it?
//
// Well, acktshuallyy... it ISN'T.
// What happens is this:
// t1 && t2 && t3 && t4 && t5 && t6
// evaluates to
// operator||(T:t1, T:t2) --> bool, ...
// so the subsequent `&&` in that expression is not about two T object, but a BOOL and a T
// and THAT particular operator&& has NOT been overloaded, so we get shortcircuit for the remainder:
// (bool) && t3 && t4 && t5 && t6
// because we did not override that particular operator.
//
// Oh, wait... --> #define EXTRA_OVERLOADS 1
//
// OMG! as you might expect from the C++ spec, now all of them `&&` and `||` in there are evaluated!
//
// Side note:
// This, of course, how brittle that prticular operator overload is, because all it takes
// is writing further complicated/compound `&&` / `||` expressions, where other types/functions
// will be involved and then, suddently and possibly quite unintuitively, some of those boolean comparisons
// are NOT dealt with operator overloads (because there isn't one for that particular combination of
// argument types) and suddenly you're looking at WTF behaviour... That's why it's very much frowned
// upon to overload `&&` and `||`.
//
ignore_unused(t1[0]);
ignore_unused(t1(1));
ignore_unused(t1->a);
ignore_unused(&t1);
ignore_unused((t1, t2));
ignore_unused(long(t1));
ignore_unused(t3 = t1);
}
int main(void) {
std::cout << "Compiler: ";
report_compiler_version();
std::cout << "Language: ";
report_cpp_language_version();
std::cout << "+ operator <=> (spaceship) supported? --> "
#ifdef SPACESHIP_OPERATOR_IS_SUPPORTED
<< "YES"
#else
<< "NO"
#endif
<< "\n";
std::cout << "+ std::format supported? ---------------> "
#ifdef STD_FORMAT_IS_SUPPORTED
<< "YES"
#else
<< "NO"
#endif
<< "\n";
std::cout << "---------------------------------------\n\n";
T_demo();
std::cout << "\n\nDone!\n\n";
return 0;
}
Compiler: gcc v16.0 (v16.0.1 20260201 (experimental))
Language: C++ v202002
C++ language version: C++20
+ operator <=> (spaceship) supported? --> YES
std::format supported? -----------------> YES
---------------------------------------
--> T(11) / (constructor)
--> T(21) / (constructor)
--> T(31) / (constructor)
--> T(41) / (constructor)
--> T(51) / (constructor)
--> T(61) / (constructor)
--> T(71) / (constructor)
--> T(81) / (constructor)
--> T(91) / (constructor)
11/21 / 71/81
--> operator==(11) / rhs:(21)
true --> operator!=(11) / rhs:(21)
false --> operator<(11) / rhs:(21)
false --> operator<=(11) / rhs:(21)
true --> operator>(11) / rhs:(21)
false --> operator>=(11) / rhs:(21)
true --> operator<=>(11) / rhs:(21)
equal
---------------------------------------
---------------------------------------
____________-- expression: t1 + t2
--> operator+(11) / rhs:(21)
--> T(102) / (constructor)
resulting value: 0 --> operator<<(102) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 + t2
---------------------------------------
--> ~T(102)
---------------------------------------
____________-- expression: t1 - t2
--> operator-(11) / rhs:(21)
--> T(113) / (copy constructor)
resulting value: 0 --> operator<<(113) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 - t2
---------------------------------------
--> ~T(113)
---------------------------------------
____________-- expression: t1 * t2
--> operator*(11) / rhs:(21)
--> T(122) / (constructor)
resulting value: 0 --> operator<<(122) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 * t2
---------------------------------------
--> ~T(122)
---------------------------------------
____________-- expression: t1 / t2
--> operator/(11) / rhs:(21)
--> T(132) / (constructor)
resulting value: 0 --> operator<<(132) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 / t2
---------------------------------------
--> ~T(132)
---------------------------------------
____________-- expression: t1 % t2
--> operator%(11) / rhs:(21)
--> T(142) / (constructor)
resulting value: 0 --> operator<<(142) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 % t2
---------------------------------------
--> ~T(142)
---------------------------------------
____________-- expression: t1 ^ t2
--> operator^(11) / rhs:(21)
--> T(152) / (constructor)
resulting value: 0 --> operator<<(152) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 ^ t2
---------------------------------------
--> ~T(152)
---------------------------------------
____________-- expression: t1 & t2
--> operator&(11) / rhs:(21)
--> T(162) / (constructor)
resulting value: 0 --> operator<<(162) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 & t2
---------------------------------------
--> ~T(162)
---------------------------------------
____________-- expression: t1 | t2
--> operator|(11) / rhs:(21)
--> T(172) / (constructor)
resulting value: 0 --> operator<<(172) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 | t2
---------------------------------------
--> ~T(172)
---------------------------------------
____________-- expression: ~t1
--> operator~(11)
--> T(182) / (constructor)
resulting value: 0 --> operator<<(182) / (ostream insertion)
^^^^^^^^^^^^-- output for: ~t1
---------------------------------------
--> ~T(182)
---------------------------------------
____________-- expression: !t1
--> operator!(11)
resulting value: false
^^^^^^^^^^^^-- output for: !t1
---------------------------------------
---------------------------------------
____________-- expression: t1 < t2
--> operator<(11) / rhs:(21)
resulting value: false
^^^^^^^^^^^^-- output for: t1 < t2
---------------------------------------
---------------------------------------
____________-- expression: t1 <= t2
--> operator<=(11) / rhs:(21)
resulting value: true
^^^^^^^^^^^^-- output for: t1 <= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 == t2
--> operator==(11) / rhs:(21)
resulting value: true
^^^^^^^^^^^^-- output for: t1 == t2
---------------------------------------
---------------------------------------
____________-- expression: t1 != t2
--> operator!=(11) / rhs:(21)
resulting value: false
^^^^^^^^^^^^-- output for: t1 != t2
---------------------------------------
---------------------------------------
____________-- expression: t1 >= t2
--> operator>=(11) / rhs:(21)
resulting value: true
^^^^^^^^^^^^-- output for: t1 >= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 > t2
--> operator>(11) / rhs:(21)
resulting value: false
^^^^^^^^^^^^-- output for: t1 > t2
---------------------------------------
---------------------------------------
____________-- expression: ordering_as_string(t1 <=> t2)
--> operator<=>(11) / rhs:(21)
resulting value: equal
^^^^^^^^^^^^-- output for: ordering_as_string(t1 <=> t2)
---------------------------------------
---------------------------------------
____________-- expression: t1 += t2
--> operator+=(11) / rhs:(21)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 += t2
---------------------------------------
---------------------------------------
____________-- expression: t1 -= t2
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 -= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 *= t2
--> operator*=(11) / rhs:(21)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 *= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 /= t2
--> operator/=(11) / rhs:(21)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 /= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 %= t2
--> operator%=(11) / rhs:(21)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 %= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 ^= t2
--> operator^=(11) / rhs:(21)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 ^= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 &= t2
--> operator&=(11) / rhs:(21)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 &= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 |= t2
--> operator|=(11) / rhs:(21)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 |= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 << t2
--> operator U(21)
--> operator<<(11) / offset:0
--> T(192) / (constructor)
resulting value: 0 --> operator<<(192) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 << t2
---------------------------------------
--> ~T(192)
---------------------------------------
____________-- expression: t1 >> t2
--> operator U(21)
--> operator>>(11) / offset:0
--> T(202) / (constructor)
resulting value: 0 --> operator<<(202) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 >> t2
---------------------------------------
--> ~T(202)
---------------------------------------
____________-- expression: t1 <<= t2
--> operator U(21)
--> operator<<=(11) / offset:0
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 <<= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 >>= t2
--> operator U(21)
--> operator>>=(11) / offset:0
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 >>= t2
---------------------------------------
---------------------------------------
____________-- expression: t1++
--> operator++(11) / (postfix ++)
--> T(213) / (copy constructor)
resulting value: 0 --> operator<<(213) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1++
---------------------------------------
--> ~T(213)
---------------------------------------
____________-- expression: ++t1
--> operator++(11) / (prefix ++)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: ++t1
---------------------------------------
---------------------------------------
____________-- expression: t1--
--> operator--(11) / (postfix --)
--> T(223) / (copy constructor)
resulting value: 0 --> operator<<(223) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1--
---------------------------------------
--> ~T(223)
---------------------------------------
____________-- expression: --t1
--> operator--(11) / (prefix --)
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: --t1
---------------------------------------
---------------------------------------
____________-- expression: t1 && t2 && t3 && t4 && t5 && t6
--> operator&&(11) / rhs:(21)
--> operator&&(---) / (special EXTRA bool && T overload) / rhs:(31)
--> operator&&(---) / (special EXTRA bool && T overload) / rhs:(41)
--> operator&&(---) / (special EXTRA bool && T overload) / rhs:(51)
--> operator&&(---) / (special EXTRA bool && T overload) / rhs:(61)
resulting value: false
^^^^^^^^^^^^-- output for: t1 && t2 && t3 && t4 && t5 && t6
---------------------------------------
---------------------------------------
____________-- expression: t1 || t2 || t3 || t4 || t5 || t6
--> operator||(11) / rhs:(21)
--> operator||(---) / (special EXTRA bool && T overload) / rhs:(31)
--> operator||(---) / (special EXTRA bool && T overload) / rhs:(41)
--> operator||(---) / (special EXTRA bool && T overload) / rhs:(51)
--> operator||(---) / (special EXTRA bool && T overload) / rhs:(61)
resulting value: true
^^^^^^^^^^^^-- output for: t1 || t2 || t3 || t4 || t5 || t6
---------------------------------------
---------------------------------------
____________-- expression: t1[0]
--> operator[](11) / pos:0
resulting value: 0 --> operator<<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1[0]
---------------------------------------
---------------------------------------
____________-- expression: t1(1)
--> operator()(11) / arg1:1
resulting value: 0
^^^^^^^^^^^^-- output for: t1(1)
---------------------------------------
---------------------------------------
____________-- expression: t1->a
--> operator->(11)
resulting value: 0
^^^^^^^^^^^^-- output for: t1->a
---------------------------------------
---------------------------------------
____________-- expression: &t1
--> operator&(11)
resulting value: 0x7ffc14dd34e4
^^^^^^^^^^^^-- output for: &t1
---------------------------------------
---------------------------------------
____________-- expression: (t1, t2)
--> operator U(21)
--> operator,(11)
--> T(233) / (copy constructor)
resulting value: 0 --> operator<<(233) / (ostream insertion)
^^^^^^^^^^^^-- output for: (t1, t2)
---------------------------------------
--> ~T(233)
---------------------------------------
____________-- expression: long(t1)
--> operator U(11)
resulting value: 0
^^^^^^^^^^^^-- output for: long(t1)
---------------------------------------
---------------------------------------
____________-- expression: t3 = t1
--> operator=(31) / rhs:(11)
--> T(243) / (copy constructor)
resulting value: 0 --> operator<<(243) / (ostream insertion)
^^^^^^^^^^^^-- output for: t3 = t1
---------------------------------------
--> ~T(243)
--> ~T(91)
--> ~T(81)
--> ~T(71)
--> ~T(61)
--> ~T(51)
--> ~T(41)
--> ~T(31)
--> ~T(21)
--> ~T(11)
Done!
Compiler: Microsoft CL v1944 (full: v194435219)
Language: C++ v202002
C++ language version: C++20
+ operator <=> (spaceship) supported? --> YES
std::format supported? -----------------> YES
---------------------------------------
--> T(11) / (constructor)
--> T(21) / (constructor)
--> T(31) / (constructor)
--> T(41) / (constructor)
--> T(51) / (constructor)
--> T(61) / (constructor)
--> T(71) / (constructor)
--> T(81) / (constructor)
--> T(91) / (constructor)
11/21 / 71/81
--> operator ==(11) / rhs:(21)
true --> operator !=(11) / rhs:(21)
false --> operator <(11) / rhs:(21)
false --> operator <=(11) / rhs:(21)
true --> operator >(11) / rhs:(21)
false --> operator >=(11) / rhs:(21)
true --> operator <=>(11) / rhs:(21)
equal
---------------------------------------
---------------------------------------
____________-- expression: t1 + t2
--> operator +(11) / rhs:(21)
--> T(102) / (constructor)
resulting value: 0 --> operator <<(102) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 + t2
---------------------------------------
--> ~T(102)
---------------------------------------
____________-- expression: t1 - t2
--> operator -(11) / rhs:(21)
--> T(113) / (copy constructor)
resulting value: 0 --> operator <<(113) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 - t2
---------------------------------------
--> ~T(113)
---------------------------------------
____________-- expression: t1 * t2
--> operator *(11) / rhs:(21)
--> T(122) / (constructor)
resulting value: 0 --> operator <<(122) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 * t2
---------------------------------------
--> ~T(122)
---------------------------------------
____________-- expression: t1 / t2
--> operator /(11) / rhs:(21)
--> T(132) / (constructor)
resulting value: 0 --> operator <<(132) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 / t2
---------------------------------------
--> ~T(132)
---------------------------------------
____________-- expression: t1 % t2
--> operator %(11) / rhs:(21)
--> T(142) / (constructor)
resulting value: 0 --> operator <<(142) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 % t2
---------------------------------------
--> ~T(142)
---------------------------------------
____________-- expression: t1 ^ t2
--> operator ^(11) / rhs:(21)
--> T(152) / (constructor)
resulting value: 0 --> operator <<(152) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 ^ t2
---------------------------------------
--> ~T(152)
---------------------------------------
____________-- expression: t1 & t2
--> operator &(11) / rhs:(21)
--> T(162) / (constructor)
resulting value: 0 --> operator <<(162) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 & t2
---------------------------------------
--> ~T(162)
---------------------------------------
____________-- expression: t1 | t2
--> operator |(11) / rhs:(21)
--> T(172) / (constructor)
resulting value: 0 --> operator <<(172) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 | t2
---------------------------------------
--> ~T(172)
---------------------------------------
____________-- expression: ~t1
--> operator ~(11)
--> T(182) / (constructor)
resulting value: 0 --> operator <<(182) / (ostream insertion)
^^^^^^^^^^^^-- output for: ~t1
---------------------------------------
--> ~T(182)
---------------------------------------
____________-- expression: !t1
--> operator !(11)
resulting value: false
^^^^^^^^^^^^-- output for: !t1
---------------------------------------
---------------------------------------
____________-- expression: t1 < t2
--> operator <(11) / rhs:(21)
resulting value: false
^^^^^^^^^^^^-- output for: t1 < t2
---------------------------------------
---------------------------------------
____________-- expression: t1 <= t2
--> operator <=(11) / rhs:(21)
resulting value: true
^^^^^^^^^^^^-- output for: t1 <= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 == t2
--> operator ==(11) / rhs:(21)
resulting value: true
^^^^^^^^^^^^-- output for: t1 == t2
---------------------------------------
---------------------------------------
____________-- expression: t1 != t2
--> operator !=(11) / rhs:(21)
resulting value: false
^^^^^^^^^^^^-- output for: t1 != t2
---------------------------------------
---------------------------------------
____________-- expression: t1 >= t2
--> operator >=(11) / rhs:(21)
resulting value: true
^^^^^^^^^^^^-- output for: t1 >= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 > t2
--> operator >(11) / rhs:(21)
resulting value: false
^^^^^^^^^^^^-- output for: t1 > t2
---------------------------------------
---------------------------------------
____________-- expression: ordering_as_string(t1 <=> t2)
--> operator <=>(11) / rhs:(21)
resulting value: equal
^^^^^^^^^^^^-- output for: ordering_as_string(t1 <=> t2)
---------------------------------------
---------------------------------------
____________-- expression: t1 += t2
--> operator +=(11) / rhs:(21)
resulting value: 0 --> operator <<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 += t2
---------------------------------------
---------------------------------------
____________-- expression: t1 -= t2
resulting value: 0 --> operator <<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 -= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 *= t2
--> operator *=(11) / rhs:(21)
resulting value: 0 --> operator <<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 *= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 /= t2
--> operator /=(11) / rhs:(21)
resulting value: 0 --> operator <<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 /= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 %= t2
--> operator %=(11) / rhs:(21)
resulting value: 0 --> operator <<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 %= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 ^= t2
--> operator ^=(11) / rhs:(21)
resulting value: 0 --> operator <<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 ^= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 &= t2
--> operator &=(11) / rhs:(21)
resulting value: 0 --> operator <<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 &= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 |= t2
--> operator |=(11) / rhs:(21)
resulting value: 0 --> operator <<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 |= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 << t2
--> operator unsigned __int64(21)
--> operator <<(11) / offset:0
--> T(192) / (constructor)
resulting value: 0 --> operator <<(192) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 << t2
---------------------------------------
--> ~T(192)
---------------------------------------
____________-- expression: t1 >> t2
--> operator unsigned __int64(21)
--> operator >>(11) / offset:0
--> T(202) / (constructor)
resulting value: 0 --> operator <<(202) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 >> t2
---------------------------------------
--> ~T(202)
---------------------------------------
____________-- expression: t1 <<= t2
--> operator unsigned __int64(21)
--> operator <<=(11) / offset:0
resulting value: 0 --> operator <<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 <<= t2
---------------------------------------
---------------------------------------
____________-- expression: t1 >>= t2
--> operator unsigned __int64(21)
--> operator >>=(11) / offset:0
resulting value: 0 --> operator <<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1 >>= t2
---------------------------------------
---------------------------------------
____________-- expression: t1++
--> operator ++(11) / (postfix ++)
--> T(213) / (copy constructor)
resulting value: 0 --> operator <<(213) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1++
---------------------------------------
--> ~T(213)
---------------------------------------
____________-- expression: ++t1
--> operator ++(11) / (prefix ++)
resulting value: 0 --> operator <<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: ++t1
---------------------------------------
---------------------------------------
____________-- expression: t1--
--> operator --(11) / (postfix --)
--> T(223) / (copy constructor)
resulting value: 0 --> operator <<(223) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1--
---------------------------------------
--> ~T(223)
---------------------------------------
____________-- expression: --t1
--> operator --(11) / (prefix --)
resulting value: 0 --> operator <<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: --t1
---------------------------------------
---------------------------------------
____________-- expression: t1 && t2 && t3 && t4 && t5 && t6
--> operator &&(11) / rhs:(21)
--> operator &&(---) / (special EXTRA bool && T overload) / rhs:(31)
--> operator &&(---) / (special EXTRA bool && T overload) / rhs:(41)
--> operator &&(---) / (special EXTRA bool && T overload) / rhs:(51)
--> operator &&(---) / (special EXTRA bool && T overload) / rhs:(61)
resulting value: false
^^^^^^^^^^^^-- output for: t1 && t2 && t3 && t4 && t5 && t6
---------------------------------------
---------------------------------------
____________-- expression: t1 || t2 || t3 || t4 || t5 || t6
--> operator ||(11) / rhs:(21)
--> operator ||(---) / (special EXTRA bool && T overload) / rhs:(31)
--> operator ||(---) / (special EXTRA bool && T overload) / rhs:(41)
--> operator ||(---) / (special EXTRA bool && T overload) / rhs:(51)
--> operator ||(---) / (special EXTRA bool && T overload) / rhs:(61)
resulting value: true
^^^^^^^^^^^^-- output for: t1 || t2 || t3 || t4 || t5 || t6
---------------------------------------
---------------------------------------
____________-- expression: t1[0]
--> operator [](11) / pos:0
resulting value: 0 --> operator <<(11) / (ostream insertion)
^^^^^^^^^^^^-- output for: t1[0]
---------------------------------------
---------------------------------------
____________-- expression: t1(1)
--> operator ()(11) / arg1:1
resulting value: 0
^^^^^^^^^^^^-- output for: t1(1)
---------------------------------------
---------------------------------------
____________-- expression: t1->a
--> operator ->(11)
resulting value: 0
^^^^^^^^^^^^-- output for: t1->a
---------------------------------------
---------------------------------------
____________-- expression: &t1
--> operator &(11)
resulting value: 00000011074FF5A0
^^^^^^^^^^^^-- output for: &t1
---------------------------------------
---------------------------------------
____________-- expression: (t1, t2)
--> operator int(21)
--> operator ,(11)
--> T(233) / (copy constructor)
resulting value: 0 --> operator <<(233) / (ostream insertion)
^^^^^^^^^^^^-- output for: (t1, t2)
---------------------------------------
--> ~T(233)
---------------------------------------
____________-- expression: long(t1)
--> operator long(11)
resulting value: 0
^^^^^^^^^^^^-- output for: long(t1)
---------------------------------------
---------------------------------------
____________-- expression: t3 = t1
--> operator =(31) / rhs:(11)
--> T(243) / (copy constructor)
resulting value: 0 --> operator <<(243) / (ostream insertion)
^^^^^^^^^^^^-- output for: t3 = t1
---------------------------------------
--> ~T(243)
--> ~T(91)
--> ~T(81)
--> ~T(71)
--> ~T(61)
--> ~T(51)
--> ~T(41)
--> ~T(31)
--> ~T(21)
--> ~T(11)
Done!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment