Named return value optimization

C++ Weekly-Ep421

Under certain circumstances, RVO may not function as expected

Example:

#include <source_location>
#include <print>
#include <expected>

using namespace std;

static void inline print_function_name(source_location const &location = source_location::current())
{
    print("{}\n", location.function_name());
}

struct S {
    S() { print_function_name(); }
    explicit S(int) { print_function_name(); }
    S(S const&) { print_function_name(); }
    S(S &&) noexcept { print_function_name(); }
    ~S() { print_function_name(); }
    S& operator=(S const&) { print_function_name(); return *this; }
    // https://devblogs.microsoft.com/cppblog/cpp23-deducing-this/
    S& operator=(this S& self, S&& other) noexcept { print_function_name(); return self; }
};

constexpr auto makeMeHappy(bool a) -> expected<S, string_view> {
    if(a) return unexpected("parse_error::invalid_input");
    // return expected<S, string_view>(in_place, 1); // RVO
    return S(1); // move ctor -> no RVO
    // return 1; // wrong with "explicit"
}

int main()
{
    S s;
    s = S(); // explicit object parameters aka deducing this

    auto const result = makeMeHappy(false);
    result.has_value() ?
        println("{}", result.value()) :
        println("{}", result.error());
}

// to rember how I have to write my own formatter
template <>
struct formatter<S> : formatter<string> {
    auto format(S const& p, format_context& ctx) const {
        return formatter<string>::format(
            "S->formated", ctx);
    }
};

Output:

__cdecl S::S(void)
__cdecl S::S(void)
struct S &__cdecl S::operator =(struct S &,struct S &&) noexcept
__cdecl S::~S(void)
__cdecl S::S(int)
__cdecl S::S(struct S &&) noexcept
__cdecl S::~S(void)
S->formated
__cdecl S::~S(void)
__cdecl S::~S(void)

only with makeMeHappy(false)

__cdecl S::S(int)
__cdecl S::S(struct S &&) noexcept
__cdecl S::~S(void)
__cdecl S::~S(void)