c – 如何为同类型提供隐式和显式转换ctr?

前端之家收集整理的这篇文章主要介绍了c – 如何为同类型提供隐式和显式转换ctr?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
给定一个简单的模板< 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.但是,不可能重载“隐式”和显式:

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;不会发出关于信息丢失的编译器警告.

解决方法

您不能在显式上重载,但您可以提供一个显式转换构造函数和隐式转换运算符:
#include <iostream>
template<typename T> struct S {
   S() {}
   template<typename U> explicit S(const S<U> &) { std::cout << "explicit\n"; }
   template<typename U> operator S<U>() { return S<U>(this); }
private:
   template<typename U> friend struct S;
   template<typename U> S(const S<U> *) { std::cout << "implicit\n"; }
};

int main() {
   S<double> sd;
   S<int> si1(sd);
   S<int> si2 = sd;
}

输出

explicit
implicit

用gcc和clang测试.

显式转换构造函数优于隐式转换运算符,因为在后一种情况下,存在对S< int>的复制构造函数的附加(可能的缓冲)调用.

猜你在找的C&C++相关文章