我有一个我打算使用的类,类型为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);
这样更好吗?
答案 0 :(得分: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 :(得分:1)
不要强制转换,而是提供一个(且只有一个)隐式转换构造函数或转换运算符。在您的情况下,它可能与operator T () const { return _data; }
答案 2 :(得分: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
。
答案 3 :(得分:0)
可以根据您提供的类型自定义类。该技术被称为模板专业化&#39;
#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()
方法,以便它可以优雅地处理转换
答案 4 :(得分: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;
};