自定义类的Static_cast会导致复制赋值失败

static_cast on custom class causes copy assignment to fail

本文关键字:复制 赋值 失败 cast Static 自定义      更新时间:2023-10-16

我期望下面的程序打印"11",但它实际上打印"01",所以看起来第一次赋值失败了。

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_);
}

如果我使用像int这样的原始类型而不是A,那么int x = 1; int y; static_cast<int>(y) = x;确实将值1分配给x。是否有一些方法可以让它为自定义类型工作?我尝试将operator A() { return *this; }添加到struct A,但没有工作。

显然这是一个愚蠢的程序,但问题出现在模板函数中,我有static_cast<std::remove_const<T>::type>(y) = x,它对基本类型工作得很好,但现在对自定义类型失败了。

与任何类型转换一样,static_cast<A>(y)y的临时副本。你可以转换为引用类型(static_cast<A&>(y));更一般地说,您可以使用std::add_lvalue_reference来实现这一点。

对于您描述的更具体的示例,您将需要const_cast而不是static_cast,但基本原理是相同的。

下面是一个编译的例子,但由于修改了const对象而有UB(因此返回0,而不是42)。在不了解更多您想要做的事情之前,为了这个示例的目的,我不会试图掩饰这一点:

#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';
}