【问题标题】:How to provide implicit and explicit conversion ctr for same type?如何为同一类型提供隐式和显式转换 ctr?
【发布时间】: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&lt;U, T&gt;::value == true如果U x; T y = x;不会发出有关信息丢失的编译器警告,它应该产生true

【问题讨论】:

  • 不,没有。你必须建立你自己的。请注意,如果不求助于编译器扩展,您将无法控制发出的警告(是否有具有这种扩展的编译器?我不知道)。
  • 事实上,我意识到我看问题的方式是错误的。我会更新我的问题。
  • @R.MartinhoFernandes:你说得对——唯一有问题的要求是警告,这是我无法控制的。如果我放弃这个,那么我只需要实现显式转换 ctr。

标签: c++ templates c++11 type-conversion


【解决方案1】:

你不能重载显式,但你可以提供显式转换构造函数和隐式转换运算符:

#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&lt;int&gt; 的复制构造函数有额外的(可能被省略)调用。

【讨论】:

  • 非常非常好!谢谢!
猜你喜欢
  • 2017-09-10
  • 2011-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多