[英]C++ How do I cast from 1 template class to another?
我有一個打算與float
或double
類型一起使用的類。 據我所知,沒有辦法限制模板選項,所以也許我在這里做危險的事情?
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.