C ++ - 在保持灵活代码的同时处理隐式/显式转换

时间:2018-03-11 19:02:39

标签: c++ casting operator-overloading explicit

我正在寻找一种方法来表达类A和内置整数类型之间的互操作性,同时保持代码的高度灵活性。例如,我希望能够在(operator &A),(AA)之间自由使用int,({{1} }和int)和(Aint),即我希望得到int的结果x = y & zx和{ {1}}类型为y或类型z,只需撰写:

class A

以下代码有效:

int

但是,如果我在x = y & z;中添加#include <cstdlib> #include <iostream> class A { public: int x; explicit A(int i) : x(i) {} operator int() { return this->x; } A operator &(const A& src) const { return A(this->x & src.x); } }; int main() { int b(2), b2(0), b3(0); A a(3); b2 = a & b; b3 = b & a; std::cout << b2 << std::endl; std::cout << b3 << std::endl; return 0; } A的新投射功能,则此功能不再有效,因为unsigned int定义在class A之间}}和operator &)以及(intint),所以当我这样做时:

int

编译器不知道unsigned int是否应该投射到b2 = a & ba,这是合乎逻辑的。我看到有两种可能性来解决它:

  1. intunsigned int之间以及operator &A之间明确实施int。我不希望这样,因为添加与其他类型的兼容性需要重新实现需要支持的所有运营商的许多组合。
  2. 强制从内置类型隐式转换为int,因此只需要AA之间的operator &
  3. 为了灵活性和可维护性,我认为解决方案2要好得多。所以我可以实现以下的A类:

    A

    现在,虽然定义了from / to int和unsigned int的转换,但我可以执行(Aclass A { public: int x; A(int i) : x(i) {} A(unsigned int i) : x(i) {} explicit operator int() { return this->x; } explicit operator unsigned int() { return static_cast<unsigned int>(this->x); } }; A operator &(const A& src1, const A& src2) { return A(src1.x & src2.x); } ),(AA), (Aint)和(intA)。

    但是我无法编译代码:

    int

    因为intb2 = a & b; b3 = b & a; b2和(b3&amp; int)(分别为a&amp; {{ 1}}))返回b并从b投射到a现在必须明确,我必须写:

    A

    我的问题(最后)是:

    有没有办法对A进行编码,以便我可以这样做:

    int

    同时只保留b2 = static_cast<int>(a & b); b3 = static_cast<int>(b & a); 的一个定义,(class Ab2 = a & b; b3 = b & a; 之间)?从理论上讲,这可以覆盖operator &A,这在技术上是不可能的。

2 个答案:

答案 0 :(得分:1)

我认为双向意味着使用独立的operator&函数:

#include <cstdlib>
#include <iostream>

using std::cout;
using std::endl;

class A
{
  int x;
public:
  explicit A(int i) : x{i}
  { }

  explicit A(unsigned i) : x{static_cast<int>(i)}
  { }

  operator int() const
  {
    return this->x;
  }

  operator unsigned() const
  {
    return static_cast<unsigned>(this->x);
  }
};

A operator&(A const& lhs, A const& rhs)
{
  return A(lhs.operator int() & rhs.operator int());
}

A operator&(A const& lhs, int rhs)
{
  return A(lhs.operator int() & rhs);
}

A operator&(int lhs, A const& rhs)
{
  return A(lhs & rhs.operator int());
}

A operator&(A const& lhs, unsigned rhs)
{
  return A(lhs.operator unsigned() & rhs);
}

A operator&(unsigned lhs, A const& rhs)
{
  return A(lhs & rhs.operator unsigned());
}

int main()
{
  auto b = 2;
  auto b2 = 0;
  auto b3 = 0;
  auto u = 2;
  auto u4 = 0u;
  auto u5 = 0u;
  auto a = A{3};

  b2 = a & b;
  b3 = b & a;
  u4 = a & u;
  u5 = u & a;

  cout << b2 << endl;
  cout << b3 << endl;
  cout << u4 << endl;
  cout << u5 << endl;
}

答案 1 :(得分:0)

我想我刚刚遇到了一个解决方案。请考虑以下代码:

class A {
public:
    int x;

    explicit A(int i) :
            x(i) {
    }

    explicit A(unsigned int i) :
            x(i) {
    }

    operator int() {
        return this->x;
    }

    operator unsigned int() {
        return static_cast<unsigned int>(this->x);
    }

};

template<typename T> A operator &(const A& src1, const T& src2) {
    return A(src1.x & src2);
}

template<typename T> A operator &(const T& src1, const A& src2) {
    return A(src1 & src2.x);
}

int main() {
    int b = 2, b2 = 0, b3 = 0;
    A a(3);

    b2 = a & b;
    b3 = b & a;

    std::cout << b2 << std::endl;
    std::cout << b3 << std::endl;

    return 0;
}

恰好工作了。我看到的唯一问题(尽管这非常重要)是你无法控制operator &对你未考虑的内置类型的影响。

然后提出新问题: 有没有办法将我的模板operator &限制为给定的类型列表(没有模板专业化)?