2015-10-23 96 views
1

我試圖讓R類T類可以轉換爲R類S,反之亦然。運算符=轉換適用於簡單的賦值,但是當它嘗試在初始化程序中使用它時,它會失敗。爲什麼?模板類型轉換運算符=

#include <array> 

template<class T> 
class Rectangle 
{ 
public : 

    Rectangle(T l, T t, T r, T b) : x1(l), y1(t), x2(r), y2(b) 
    { 

    } 

    template<class S> 
    Rectangle<T> & operator = (Rectangle<S> const & o) 
    { 
     x1 = static_cast<T>(o.x1); 
     y1 = static_cast<T>(o.y1); 
     x2 = static_cast<T>(o.x2); 
     y2 = static_cast<T>(o.y2); 

     return *this; 
    } 

    T x1, y1, x2, y2; 
}; 

int main(void) 
{ 
    auto foo = Rectangle<float>(1.0f, 2.0f, 3.0f, 4.0f); 
    auto bar = Rectangle<double>(1.0, 2.0, 3.0, 4.0); 

    { 
     foo = bar; // Converts, ok. 
    } 

    { 
     auto arr = std::array<Rectangle<float>, 2>() = {{ 
      foo, 
      bar // Error - no appropriate default constuctor 
     }}; 
    } 

    return 0; 
} 

編輯:我使用Visual Studio 2013年

回答

3

這裏有兩個問題。第一:

auto arr = std::array<Rectangle<float>, 2>() = ... 

Rectangle<T>不是默認 - 構造的,所以()將無法​​正常工作。無論如何,鑑於第二=,我懷疑這只是一個錯字。一旦你解決這個問題:

auto arr = std::array<Rectangle<float>, 2>{{ 
     foo, 
     bar // Still error 
    }}; 

現在,你有一個賦值操作符,但我們沒有分配。我們正在建設。所以,你需要的是一個構造函數:

template <class S> 
Rectangle(Rectangle<S> const& o) 
    : x1(o.x1) 
    , y1(o.y1) 
    , x2(o.x2) 
    , y2(o.y2) 
{ } 
+0

我看到你的答案*可能*正確,也許我使用Visual Studio 2013的事實是這裏的問題。我嘗試了構造函數,它沒有任何區別。刪除=是一個語法錯誤(「expected a;」)。 – Robinson

+0

@Robinson有兩個'='s顯然是錯誤的。你有'auto x = T()= {{...}};',它試圖分配一個右值。這可能是VS13不支持支持正確初始化?我不熟悉它的侷限性。 – Barry

+0

我不認爲它是,不。我必須像這樣初始化std :: array。我會在2015年之後嘗試。 – Robinson

0

爲了使A類可轉換到你需要定義一個轉換操作符,而不是一個賦值運算符B類。

例子:

operator B() { 
    B b; 
    b.populate_from(this); 
    return b; 
} 
1

你需要的是轉換「複製」構造

template<class S> 
Rectangle(Rectangle<S> const & o) : Rectangle(o.x1, o.x2, o.y1, o.y2) 

當你寫的代碼,如:

A x = {a}; 

你真的使用構造函數(與a作爲參數),而不是一個賦值運算符。