【问题标题】:Create own operator ** in C++?在 C++ 中创建自己的运算符 **?
【发布时间】:2017-12-17 11:42:59
【问题描述】:

有一个泛型类 Vector 扩展了 std::array,还有一个泛型类 Expression 定义了向量的可能表达式。

例如:

向量 A({1,2,3});

向量 B({2,2,2});

和表达式:

A + B;

A * B;

A - B;

A / B;

现在我需要这个表达式 A ** B,它返回一个 double 作为两个向量 A 和 B 的标量产生,结果必须是:2+4+6=12。问题是operator**的实现!!!

我该如何写这个操作符**?

我的想法是重载 Vector 的解引用 operator* 返回一个指针,然后重载 struct-Mul oder multiply operator* ...无法解决此错误:

“不存在从“Expression”到“double”的合适转换函数”

template<typename Left, typename Op, typename Right> class Expression {
    const Left& m_left;
    const Right& m_right;

public:
    typedef typename Left::value_type value_type;

    // Standard constructor
    Expression(const Left& l, const Right& r) : m_left{ l }, m_right{ r } {}

    size_t size() const {
        return m_left.size();
    }

    value_type operator[](int i) const {
        return Op::apply(m_left[i], m_right[i]);
    }
};

struct Mul {
    template<typename T> static T apply(T l, T r) {
        return l * r;
    }
};

template<typename Left, typename Right>
Expression<Left, Mul, Right> operator*(const Left& l, const Right& r) {
    return Expression<Left, Mul, Right>(l, r);
}

.......................

// Class Vector extends std::array
template<class T, size_t S> class Vector : public array<T, S> {

public:
    // Standard constructor
    Vector<T, S>(array<T, S>&& a) : array<T, S>(a) {}

    // Initializerlist constructor
    Vector(const initializer_list<T>& data) {
        size_t s = __min(data.size(), S);
        auto it = data.begin();
        for (size_t i = 0; i < s; i++)
            this->at(i) = *it++;
    }
};

.....................................

int main {

    Vector<double, 5> A({ 2, 3, 4, 5, 6 });
    Vector<double, 5> B({ 3, 3, 3, 3, 3 });
    Vector<double, 5> C;
    C = A * B; // is a Vector: [6, 9, 12, 15, 18] and it works.

    double d = A**B;  // but this one does not work, the error message is: "no suitable conversion function from "Expression<Vector<double, 5U>, Mul, Vector<double, 5U> *>" to "double" exists"

    cout << d << endl; // must give me: 60
}

【问题讨论】:

  • 你这样做:dot(A, B)。哪个被误导的灵魂表示与** 的标量积?!!!
  • 是的,你是对的!但这是学校的作业:(一定是这样的!!!
  • 您需要说明这是一项家庭作业,并且您必须完全按照问题中直接说明的方式实施。
  • 重新打开,这个问题不是关于为内置类型实现**,而且按要求去做并非不可能。
  • 没有内置运算符**,所以不能重载。如果您使用* * 调用它,您可能想出的任何让您使用** 的解决方法也将起作用。这是一个奇怪且具有误导性的任务。

标签: c++ overloading operator-keyword


【解决方案1】:

你可以这样做

#include <iostream>
using namespace std;

struct V
{
  struct Vhelper
  {
   Vhelper(const V& v) : v(v) {}
   const V& v; 
  };

  V operator*(const V&) const {
     cout << "* called\n";
     return V();
  }
  double operator*(const Vhelper&) const {
     cout << "** called\n";
     return 42;
  }
  Vhelper operator*() { return Vhelper(*this); }
};

int main() {
    V a, b, c;
    a = b * c;
    double d = b ** c;
    return 0;
}

但你应该忘记,在你的作品被评分后,这是可能的。永远不要在实际代码中这样做。

这不是一个完整的operator**,因为它不能在所有上下文中使用真正的** 运算符(如果你想将它用于幂运算,它有错误的优先级和关联性) .但是对于一个有趣的学习项目来说应该没问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 1970-01-01
    • 2015-04-11
    相关资源
    最近更新 更多