2015-08-23 55 views
1

我有一個課程,我打算使用與類型floatdouble。據我所知,沒有辦法限制模板選項,所以也許我可能會在這裏做一些危險的事情?C++如何從1模板類投射到另一個模板類?

template<class T> 
class A 
{ 
    A(T arg) { _data = arg; } 

    T _data; 
} 

typedef A<float> A_f; 
typedef A<double> A_d; 

我該怎麼做?

int main() 
{ 
    A_f f(3.1415); 
    A_d d(3.1415); 
    f = (A_f)d; 
} 

IE:將包含double類型數據的類轉換爲包含float類型數據的類。

編輯:這似乎並沒有在任何地方去,所以我想這個玩弄,但很明顯,我不知道在這裏做什麼,因此不會編譯...

template<class T> 
class A 
{ 
    friend     // Intention is for T to be double here 
    A<float> operator A<float>(const A<T> input); 
} 

A<float> operator A<float>(const A<double> input) 
{ 
    return A<float>(input._data); 
} 

也許這有助於解釋我想實現的目標?

亞當

第二個編輯:

return A<float>((float)input._data); 

這是更好?

+0

完全相同的方式,你會怎麼做,如果你沒」不要使用模板。 – Adam

+0

@ n.m。這並不回答 – user3728501

+0

@ n.m。我嘗試了谷歌搜索,我還沒有找到相關信息 – user3728501

回答

0

有一個選項可以根據您提供的類型自定義一個類。該技術被稱爲「模板專業化」

#include <iostream> 
using namespace std; 

template <typename T> 
class A { 
public: 
    void print_my_type() { 
     cout << "Generic template instance" << endl; 
    } 

    explicit operator A<int>() const { 
     cout << "Casting to int" << endl; 
     return A<int>(); 
    } 
}; 

template <> 
class A<int> { 
public: 
    void print_my_type() { 
     cout << "Class templated with an int" << endl; 
    } 

    explicit operator A<double>() const { 
     cout << "Casting to double" << endl; 
     return A<double>(); 
    } 
}; 

int main() { 
    A<double> a; 
    A<int> b; 

    a.print_my_type(); 
    b.print_my_type(); 

    a = static_cast<A<double>>(b); 

    return 0; 
} 

您不應該投射那樣的對象。如果你打算有一個對象,你想投向另一個。您應該提供一個operator A()方法,以便它可以正常處理轉換

+0

這不是打敗了模板的觀點嗎?你必須爲每種類型再次寫出課程? – user3728501

+0

@ n.m。儘管這是有用的信息。 – user3728501

+0

很多模板類都是以這種方式專門設計的。像'std :: unordered_map'。當你的代碼運行時,沒有模板類。所有對模板類型的引用已被解析@n.m。 OP問道:「據我所知,沒有辦法限制模板選項」,所以它在一定程度上回答了它。另外我還提供了一個隱含的「如何從一個類到另一個類正確投射」的答案 –

1

不要投射,但提供一個(且只有一個)隱式轉換構造函數或轉換運算符。你的情況可能是微不足道的operator T() const { return _data; }

+0

這應該作爲外部(朋友?)成員函數實現嗎?在這種情況下,什麼是參數和返回值? – user3728501

+0

@ user3728501只是一個內聯成員函數(運算符),它太瑣碎了 –

2

你可以使用std::enable_if只允許某些類型:

#include <type_traits> 
using namespace std; 

// Our catch-all is not defined, so will not compile 
// Could also be made to print a nice error message 
template<typename T, typename Sfinae = void> class A; 

// Ok if T is float or double 
template<typename T> 
class A<T, typename std::enable_if<std::is_same<T, float>::value 
           || std::is_same<T, double>::value>::type> 
{ 
    // Your class here 
}; 

int main() 
{ 
    A<int> a; // FAILS 
    A<float> b; // Ok 
    A<double> c; // Ok 

    return 0; 
} 

然後你只需要在你的類定義轉換運營商投工作。

1

我將第二,你不應該投這樣的,但如果你堅持,添加一個模板拷貝構造函數的參數:

template<class T> 
class A 
{ 
public:         // add this 
    A(T arg) { _data = arg; } 

    template <class U>     // add this 
    A(A<U> arg) { _data = arg._data; } // add this 

    T _data; 
} 

這將然後允許從A<U>轉換到A<T>只要U是可以隱式轉換爲T

+0

你更喜歡第二次編輯嗎? (一秒) – user3728501

+0

我不知道你的意思。你想寫一個類型轉換操作符嗎?這個答案使你的原始代碼編譯。 – Adam

+0

@ user3728501我編輯了我的答案,明確了我的意思。這使得你原來的'f =(A_f)d''行工作。 – Adam

0

實例與模板轉換操作符+ static_assert類型驗證:

http://coliru.stacked-crooked.com/a/6b01010ea5f02aee

#include <vector> 
#include <iostream> 

template < typename T > class TD; // type visualiser 

template<class T> 
class A 
{ 
    public: 
    A(T arg) { _data = arg; } 

    template<typename D> 
    operator A<D>() { 
     static_assert(std::is_same<D, float>::value || std::is_same<D, double>::value, "double/floats allowed only"); 
     //TD<D>(); // D is float here 
     return static_cast<D>(_data); 
    } 

    T _data; 
}; 

typedef A<float> A_f; 
typedef A<double> A_d; 
typedef A<int> A_i; 

int main() { 
    A_f f(3.14151); 
    A_d d(3.14152); 

    std::cout << f._data << std::endl; 
    std::cout << d._data << std::endl;  

    f = (A_f)d; 
    //f = (A_i)d; // static assertion here 

    std::cout << f._data << std::endl; 
    return 0; 
} 

[編輯]

template<class T> 
class A 
{ 
public: 
    A(T arg) { _data = arg; } 

    template<typename D> 
    operator A<D>() { 
    static_assert(std::is_same<D, float>::value || std::is_same<D, double>::value, "double/floats allowed only"); 
    //TD<D>(); // D is float here 
    return A<D>(static_cast<D>(_data)); 
    } 

    T _data; 
}; 
+0

要麼我不明白這個或你的行的語法'返回static_cast (_data);'沒有任何意義 - 當然這會返回一個類型'D'而不是'A '? – user3728501

+0

@ user3728501它正在使用隱式構造函數 - 臨時正在構建並返回。我已經用明確的結構更新了答案。 – marcinj

+0

啊,我看到謝謝 – user3728501