【发布时间】:2012-12-01 03:19:47
【问题描述】:
给定一个简单的template <typename T> struct X { T x, y; };,我想提供转换构造函数以便用户可以编写:
X<double> a;
X<int16_t> b = a; // uses implicit conversion ctr (compiles with warning)
X<int16_t> c(a); // uses explicit conversion ctr (compiles w/o warning)
X<int32_t> d = c; // uses implicit conversion ctr (compiles w/o warning)
我相信要实现这个目标,我需要同时实现 U 类型的隐式和显式转换构造函数。但不可能重载“隐式”和explicit:
template <typename T> struct X {
X(T x = T(), T y = T()) : x(x), y(y) {}
// implicit conversion
template <typename U>
X(const X<U>& other) : x(other.x), y(other.y) {}
// not possible!
template <typename U>
explicit X(const X<U>& other)
: x(static_cast<T>(other.x))
, y(static_cast<T>(other.y))
{}
T x, y;
};
我怎样才能实现这个目标(我想我不能......)?
我最初的想法是 我需要根据is_lossless_convertible 启用/禁用一个或另一个。那么有合适的类型特征吗?
我想测试 标量 类型 U 是否可以在不损失精度的情况下转换为 T 类型:
using namespace std;
static_assert(is_lossless_convertible<int16_t, int32_t>::value == true);
static_assert(is_lossless_convertible<int32_t, int16_t>::value == false);
static_assert(is_lossless_convertible<int16_t, uint32_t>::value == false);
static_assert(is_lossless_convertible<int32_t, double>::value == true);
static_assert(is_lossless_convertible<double, int32_t>::value == false);
简而言之,如果std::is_convertible<U, T>::value == true和如果U x; T y = x;不会发出有关信息丢失的编译器警告,它应该产生true。
【问题讨论】:
-
不,没有。你必须建立你自己的。请注意,如果不求助于编译器扩展,您将无法控制发出的警告(是否有具有这种扩展的编译器?我不知道)。
-
事实上,我意识到我看问题的方式是错误的。我会更新我的问题。
-
@R.MartinhoFernandes:你说得对——唯一有问题的要求是警告,这是我无法控制的。如果我放弃这个,那么我只需要实现显式转换 ctr。
标签: c++ templates c++11 type-conversion