c++ - 表达式模板的核心功能 : assignment operator sub-template type?

标签 c++ templates

如果标题听起来令人困惑,我很抱歉,但问题是。我正在研究一个非常简约的案例 Expression Templates (请参阅下面的完整 C++98 代码)并且我了解所有内容,除了一个细节:为什么 Vector 类型的赋值运算符需要有一个外国或第三方模板 A 才能工作?请参阅下面带注释的行(抱歉找不到行号的方法)

#include <iostream>
using namespace std;

template <class A>
struct Expr {
    inline operator const A&() const {
        return *static_cast<const A*>(this);
    }
};

// ----------------------------------------------
// Addition Expression
// ----------------------------------------------
template<class A, class B>
class DExprSum : public Expr< DExprSum< A,B > > {
    const A& a_;
    const B& b_;

public:
    DExprSum(const A& a, const B& b) : a_(a), b_(b) { }

    double operator()(int i) const {
        return (double)(a_[i] + b_[i]);
    }

    double operator[](int i) const {
        return this->operator()(i);
    }
};

template <class A, class B>
inline DExprSum<A, B> operator+(const Expr<A>& a, const Expr<B>& b) {
    return DExprSum<A, B>(a, b);
};

// ----------------------------------------------
// A simple vector class
// ----------------------------------------------
template<class T>
class Vector : public Expr<Vector<T> > {

private:
    T *p;
    int len;

public:
    Vector(int length) {
        len = length;
        p = new T[length];
    };

    T operator()(int i) const {
        return p[i];
    }

    T& operator[](int i) const {
        return p[i];
    }

    // <<<<<<------------ HERE why do I need a new template<class A>
    // rather than simply using Expr<Vector<T> > 
    template<class A>
    void operator=(const Expr<A>& expr) {
        const A& a(expr);

        // parallelize using OpenMP
        #pragma omp parallel for schedule(runtime) // OMP_SCHEDULE=static,50 OMP_NUM_THREADS=10
        for (int i=0; i < len; ++i) {
            p[i] = a(i);
        }
    }

    ~Vector() {
        delete[] p;
    };
};

int main() {
    Vector<double> a(3);
    Vector<double> b(3);
    Vector<double> c(3);

    a[0] = 1;
    a[1] = 2;
    a[2] = 3;

    b[0] = 2;
    b[1] = 3;
    b[2] = 4;

    c = a + a + b + b;

    for (int i = 0; i < 3; ++i) {
            cout << c[i] << endl;
    }

    return 0;
}

如果我将赋值运算符定义更改为(这就是它的实际意图):

void operator=(const Expr<Vector<T> >& expr) {
    const Vector<T>& a(expr);

    // parallelize using OpenMP
    #pragma omp parallel for schedule(runtime) // OMP_SCHEDULE=static,50 OMP_NUM_THREADS=10
    for (int i=0; i < len; ++i) {
        p[i] = a(i);
    }
}

我收到编译器错误错误:没有可行的重载'='

最佳答案

因为参数传递给 Vector<T>::operator=不是Expr<Vector<T>> (特别是对于使用表达式模板的情况)。

对于c = a + a + b + b; ,您正在调用operator+()三次,操作和参数保存在表达式模板中。返回值a + a + b + b将是

DExprSum<DExprSum<DExprSum<Vector<double>, Vector<double>>, Vector<double>>, Vector<double>>

可以转换为

Expr<DExprSum<DExprSum<DExprSum<Vector<double>, Vector<double>>, Vector<double>>, Vector<double>>>

然后解析模板参数A

DExprSum<DExprSum<DExprSum<Vector<double>, Vector<double>>, Vector<double>>, Vector<double>>`

但它不能转换为Expr<Vector<double>> .

编辑

对于附加问题,

operator=这里是一个模板函数。并且不需要指定模板参数,因为 Template argument deduction调用模板函数时。

关于c++ - 表达式模板的核心功能 : assignment operator sub-template type?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35741362/

相关文章:

c++ - C++ (GCC) 中的四倍精度

c++ - SFINAE用于非成员运算符重载

eclipse - 在 Eclipse 中定制新的 JUnit 模板?

css - Joomla 文章/列插入填充

C++ Builder - 将 TIdHashSHA256 与 OpenSSL 结合使用

c++ - 使用 vmime 构建电子邮件时出现乱码

c++ - 可以将不同的 .dwo 文件合并为一个吗?

c++ - Qt 字符指针数组

c++ - 为模板类重载运算符 << 时出现链接器错误

django - 在 Django 中使用 Jinja2 模板有什么缺点或陷阱吗?