错误:表达式必须是可修改的lvalue

时间:2020-12-30 22:44:59

I have been getting this error come up in the for loop when I try to assign values to x_dev, y_dev, and pearson. As far as I can see they should all be modifiable. Can anyone see where I have gone wrong?

当我试图给x_dev、y_dev和pearson赋值时,在for循环中出现了这个错误。在我看来,它们都是可以修改的。有人能看出我哪里做错了吗?

class LoopBody
{  
    double *const x_data;
    double *const y_data;
    double const x_mean;
    double const y_mean;  
    double x_dev;
    double y_dev;
    double pearson; 


public:
    LoopBody(double *x, double *y, double xmean, double ymean, double xdev, double ydev, double pear) 
            : x_data(x), y_data(y), x_mean(xmean), y_mean(ymean), x_dev(xdev), y_dev(ydev), pearson(pear) {}  

    void operator() (const blocked_range<size_t> &r) const {              
        for(size_t i = r.begin(); i != r.end(); i++)
        {
            double x_temp = x_data[i] - x_mean;
            double y_temp = y_data[i] - y_mean;

            x_dev += x_temp * x_temp;
            y_dev += y_temp * y_temp;

            pearson += x_temp * y_temp;

        }
    }
};

Having followed @Bathsheba 's advice I have overcome these problems. However When running a parallel_for the operator is runs but the for loop is never entered.

我听从了芭丝谢芭的建议,克服了这些问题。然而,当运行运算符的parallel_for时,却从未输入for循环。

This is where I call the parallel_for:

我把这个叫做parallel_for:

parallel_for(blocked_range<size_t>(0,n), LoopBody(x, y, x_mean, y_mean, x_dev, y_dev, pearson), auto_partitioner());

2 个解决方案

#1


2  

The () operator is marked const, and you're attempting to modify class member data (e.g. x_dev, y_dev and person). That is not allowed and is why you're getting the compile-time error.

操作符被标记为const,您正在尝试修改类成员数据(例如x_dev、y_dev和person)。这是不允许的,这也是为什么会出现编译时错误。

You probably want to drop the const from the method.

您可能想从方法中删除const。

Alternatively you can mark the member data that you want to modify as mutable, but this is not the preferred solution as it makes code brittle, difficult to read and can wreak havoc with multi-threading.

您也可以将想要修改的成员数据标记为可变的,但这不是首选的解决方案,因为它使代码变得脆弱、难于读取,并可能对多线程造成破坏。

#2


2  

Seemingly you want to do reduction, i.e. compute some aggregate values over the data.

看起来您想要做的是简化,例如计算数据上的聚合值。

For that, TBB offers a special function template: parallel_reduce. Unlike parallel_for that perhaps you use now, parallel_reduce does not require operator() of a body class to be const, because an instance of that class accumulates partial results. However, it poses other requirements to the class: the need to have a special constructor as well as a method to merge partial results from another body instance.

为此,TBB提供了一个特殊的函数模板:parallel_reduce。与您现在使用的可能是parallel_reduce不同,它不要求body类的运算符()是const,因为该类的一个实例积累了部分结果。但是,它对类提出了其他要求:需要有一个特殊的构造函数以及一个方法来合并来自另一个body实例的部分结果。

More information can be found in the Intel(R) TBB User Guide: http://www.threadingbuildingblocks.org/docs/help/tbb_userguide/parallel_reduce.htm

更多信息可以在Intel(R) TBB用户指南中找到:http://www.threadingbuildingblocks.org/docs/help/tbb_userguide/parallel_reduce.htm

Also there is an overload of parallel_reduce which takes two functors - one for body and another one for merging partial results - as well as a special "identity" value used to initialize accumulators. But you are computing three aggregate values at once, so you would still need to have a struct or class to store all three values in a single variable.

此外,还需要两个函数符(一个用于body,另一个用于合并部分结果)以及一个用于初始化累加器的特殊“标识”值,从而使parallel_reduce超负荷。但是您同时要计算三个聚合值,所以您仍然需要一个struct或类来将这三个值存储在一个变量中。

#1


2  

The () operator is marked const, and you're attempting to modify class member data (e.g. x_dev, y_dev and person). That is not allowed and is why you're getting the compile-time error.

操作符被标记为const,您正在尝试修改类成员数据(例如x_dev、y_dev和person)。这是不允许的,这也是为什么会出现编译时错误。

You probably want to drop the const from the method.

您可能想从方法中删除const。

Alternatively you can mark the member data that you want to modify as mutable, but this is not the preferred solution as it makes code brittle, difficult to read and can wreak havoc with multi-threading.

您也可以将想要修改的成员数据标记为可变的,但这不是首选的解决方案,因为它使代码变得脆弱、难于读取,并可能对多线程造成破坏。

#2


2  

Seemingly you want to do reduction, i.e. compute some aggregate values over the data.

看起来您想要做的是简化,例如计算数据上的聚合值。

For that, TBB offers a special function template: parallel_reduce. Unlike parallel_for that perhaps you use now, parallel_reduce does not require operator() of a body class to be const, because an instance of that class accumulates partial results. However, it poses other requirements to the class: the need to have a special constructor as well as a method to merge partial results from another body instance.

为此,TBB提供了一个特殊的函数模板:parallel_reduce。与您现在使用的可能是parallel_reduce不同,它不要求body类的运算符()是const,因为该类的一个实例积累了部分结果。但是,它对类提出了其他要求:需要有一个特殊的构造函数以及一个方法来合并来自另一个body实例的部分结果。

More information can be found in the Intel(R) TBB User Guide: http://www.threadingbuildingblocks.org/docs/help/tbb_userguide/parallel_reduce.htm

更多信息可以在Intel(R) TBB用户指南中找到:http://www.threadingbuildingblocks.org/docs/help/tbb_userguide/parallel_reduce.htm

Also there is an overload of parallel_reduce which takes two functors - one for body and another one for merging partial results - as well as a special "identity" value used to initialize accumulators. But you are computing three aggregate values at once, so you would still need to have a struct or class to store all three values in a single variable.

此外,还需要两个函数符(一个用于body,另一个用于合并部分结果)以及一个用于初始化累加器的特殊“标识”值,从而使parallel_reduce超负荷。但是您同时要计算三个聚合值,所以您仍然需要一个struct或类来将这三个值存储在一个变量中。