George Skelton George Skelton - 8 months ago 21
C++ Question

static_cast on custom class causes copy assignment to fail

I expected the following program to print "11" but it actually prints "01" so it seems like the first assignment fails.

struct A
A(int i = 0) : i_(i) {}
int i_;

int main()
A x(1);
A y;
static_cast<A>(y) = x; // *** Fails to assign ***
std::printf("%i", y.i_);
y = x;
std::printf("%i", y.i_);

If I use a primitive type like
instead of
int x = 1; int y; static_cast<int>(y) = x;
does assign the value
. Is there some way I can get it to work for custom types? I tried adding
operator A() { return *this; }
struct A
but that didn't work.

Obviously this is a stupid program but the problem arises in a template function where I have
static_cast<std::remove_const<T>::type>(y) = x
and it was working fine for primitive types but just now failed for a custom type.


As with any cast, static_cast<A>(y) is a temporary copy of y.

You can cast to a reference type instead (static_cast<A&>(y)); more generally, you could achieve this with std::add_lvalue_reference.

For the more specific example you described, you'll need const_cast rather than static_cast, but the basic principle is the same.

Here's an example that compiles, but has UB because of the modification of a const object (and thus returns 0, not 42). Without knowing more about what you're trying to do, I shan't attempt to disguise that for the purposes of this example:

#include <iostream>
#include <type_traits>

template <typename T>
T foo(T val)
    T x{};

    using not_const = typename std::remove_const<T>::type;
    using ref_type  = typename std::add_lvalue_reference<not_const>::type;

    const_cast<ref_type>(x) = val;

    return x;

int main()
    std::cout << foo<const int>(42) << '\n';