簡體   English   中英

C ++如何將一個模板類轉換為另一個模板類?

[英]C++ How do I cast from 1 template class to another?

我有一個打算floatdouble類型一起使用的類。 據我所知,沒有辦法限制模板選項,所以也許我在這里做危險的事情?

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

這是否更好?

您可以使用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;
}

然后,您只需要在類中定義一個轉換運算符即可進行強制轉換。

不強制轉換,而是提供一個(並且僅一個)隱式轉換構造函數或轉換運算符。 在您的情況下,它可能與operator T () const { return _data; }一樣瑣碎operator T () const { return _data; } operator T () const { return _data; }

我將緊跟您不應該那樣轉換的參數,但是如果您堅持要添加一個模板化的副本構造函數:

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

有一個選項可根據您提供的類型自定義類。 該技術稱為“模板專業化”

#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()方法,以便它可以正常處理轉換

帶有類型轉換的模板轉換運算符+ 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;
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM