自定义类上的static_cast导致复制分配失败

时间:2016-09-19 18:36:30

标签: c++

我希望以下程序打印“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的模板函数中,它对原始类型工作正常,但现在对于自定义类型失败了。

1 个答案:

答案 0 :(得分:4)

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

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

由于修改了const对象(因此返回0,而不是42),因此an example that compiles, but has UB {{3}}。如果不了解您正在尝试做的事情,我不会为了这个例子的目的而试图掩饰这一点:

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