2016-09-19 40 views
0

我期望以下程序打印「11」,但它實際上打印「01」,因此看起來第一次分配失敗。自定義類上的static_cast導致複製分配失敗

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

'的static_cast (Y)'' – David

+0

的std :: remove_const'應使用*極端*謹慎而不輕鬆 - 引入未定義行爲的風險很大。 –

回答

4

與其他演員一樣,static_cast<A>(y)y的臨時副本。您可以轉換爲參考類型(static_cast<A&>(y));更一般地說,你可以用std::add_lvalue_reference來實現。

對於您描述的更具體的示例,您需要const_cast而不是static_cast,但基本原理是相同的。

這裏的an example that compiles, but has UB由於const對象(因此返回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'; 
} 
+0

謝謝你,這是有道理的。但是,如果只將值分配給臨時副本,爲什麼它可以用於原始類型? –

+0

@GeorgeSkelton:[不](https://ideone.com/T5Hyqi)。 –

+0

但是'int x = 1; int y = 0; static_cast (y)= x; std :: cout << y;'打印'1' –

相關問題