Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何执行运算符重载以避免c++;?_C++ - Fatal编程技术网

C++ 如何执行运算符重载以避免c++;?

C++ 如何执行运算符重载以避免c++;?,c++,C++,我举以下例子来说明我的问题: bool bSign; // bSign will be set depending on some criteria, which is omitted here. // b[][][] is a float array, which is initialized in the program for(int i=0; i<1000; i++) for(int j=0; j<10000; j++) for(int

我举以下例子来说明我的问题:

 bool bSign;
 // bSign will be set depending on some criteria, which is omitted here.
 // b[][][] is a float array, which is initialized in the program  
 for(int i=0; i<1000; i++)
     for(int j=0; j<10000; j++)
         for(int k=0; k<10000; k++)
             if(bSign)
                 a[i][j][k] = (b[i][j][k]>500);
             else
                 a[i][j][k] = (b[i][j][k]<500);
boolbsign;
//bSign将根据某些标准进行设置,此处省略。
//b[]是一个浮点数组,在程序中初始化
对于(int i=0;i,如果编译器知道
bSign
在循环过程中不会更改,那么它应该能够优化此设置。使其
const
会有所帮助

如果由于某种原因没有发生这种情况,您可以将
If(bSign)
移出以包围整个嵌套循环集(基本上,手动执行希望编译器为您执行的操作)

除此之外,您还依赖于分支预测(其成功与否取决于数据的性质)

不过,运算符重载与此完全无关

实际上,这种迭代是没有效率的。难道你找不到更好的算法吗?

如果你的编译器知道
bSign
在循环过程中不会改变,那么它应该能够优化这个问题。使它成为
const
会有所帮助

如果由于某种原因没有发生这种情况,您可以将
If(bSign)
移出以包围整个嵌套循环集(基本上,手动执行希望编译器为您执行的操作)

除此之外,您还依赖于分支预测(其成功与否取决于数据的性质)

不过,运算符重载与此完全无关


实际上,这种迭代是没有效率的。难道你找不到更好的算法吗?

你能把支票移出循环吗

if (bSign)
    for(int i=0; i<1000; i++)
        for(int j=0; j<10000; j++)
            for(int k=0; k<10000; k++)
                a[i][j][k] = (b[i][j][k]>500);
else
    for(int i=0; i<1000; i++)
        for(int j=0; j<10000; j++)
            for(int k=0; k<10000; k++)
                a[i][j][k] = (b[i][j][k]<500);
if(bSign)

对于(int i=0;i您可以将支票移出循环吗

if (bSign)
    for(int i=0; i<1000; i++)
        for(int j=0; j<10000; j++)
            for(int k=0; k<10000; k++)
                a[i][j][k] = (b[i][j][k]>500);
else
    for(int i=0; i<1000; i++)
        for(int j=0; j<10000; j++)
            for(int k=0; k<10000; k++)
                a[i][j][k] = (b[i][j][k]<500);
if(bSign)

对于(int i=0;i),我认为您不能在程序中除去这些IFS。但是您可以帮助处理器更快地运行程序。考虑排序<代码> b>代码>数组(或者如果不能更改<代码> B<代码>,请复制和排序)这当然有助于通过处理器来预测分支。当然,可以确定一些基准,以确保它不会比当前的代码更坏。

< P>我认为您不能在程序中除去这些IFS。但是您可以帮助处理器更快地运行程序。考虑排序<代码> B<代码>数组(如果不能更改<代码> B<代码>,请复制和排序)。。这将有助于按处理器预测分支。当然,要做一些基准测试,以确保不会比当前代码更糟糕。

我不确定这是否更快(您必须进行性能检查),但您可以使用函数指针避免所有if语句

int comparisonValue = 500;
auto greater = [comparisonValue](float val) {
    return val > comparisonValue;
};
auto lesser = [comparisonValue](float val) {
    return val < comparisonValue;
};

bool bSign;
// bSign will be set depending on some criteria, which is omitted here.
// b[][][] is a float array, which is initialized in the program  
decltype(greater)* funcPtr;

if(bSign) {
    funcPtr = &greater;
} else {
    funcPtr = &lesser;
}


for(int i=0; i<1000; i++)
    for(int j=0; j<10000; j++)
        for(int k=0; k<10000; k++)
            a[i][j][k] = (*funcPtr)(b[i][j][k]);
int comparisonValue=500;
自动增大=[comparisonValue](浮点值){
返回值>比较值;
};
自动较小=[comparisonValue](浮点值){
返回值<比较值;
};
bool-bSign;
//bSign将根据某些标准进行设置,此处省略。
//b[]是一个浮点数组,在程序中初始化
decltype(更大)*funcPtr;
如果(b签名){
funcPtr=&更大;
}否则{
funcPtr=&less;
}

对于(int i=0;i我不确定这是否更快(您必须进行性能检查),但可以使用函数指针避免所有if语句

int comparisonValue = 500;
auto greater = [comparisonValue](float val) {
    return val > comparisonValue;
};
auto lesser = [comparisonValue](float val) {
    return val < comparisonValue;
};

bool bSign;
// bSign will be set depending on some criteria, which is omitted here.
// b[][][] is a float array, which is initialized in the program  
decltype(greater)* funcPtr;

if(bSign) {
    funcPtr = &greater;
} else {
    funcPtr = &lesser;
}


for(int i=0; i<1000; i++)
    for(int j=0; j<10000; j++)
        for(int k=0; k<10000; k++)
            a[i][j][k] = (*funcPtr)(b[i][j][k]);
int comparisonValue=500;
自动增大=[comparisonValue](浮点值){
返回值>比较值;
};
自动较小=[comparisonValue](浮点值){
返回值<比较值;
};
bool-bSign;
//bSign将根据某些标准进行设置,此处省略。
//b[]是一个浮点数组,在程序中初始化
decltype(更大)*funcPtr;
如果(b签名){
funcPtr=&更大;
}否则{
funcPtr=&less;
}

对于(int i=0;i,正如许多人所说,最好将
if
语句移出循环(如果可能)。为了防止代码重复,可以使用函数指针,但如果有真正的调用,情况可能会更糟。如果
调用比简单的
if
调用成本更高。如果编译器可以内联它们,就可以了

您还可以通过以下方式使用模板元编程(本例中为简单模板算法):

 template<typename ComparatorT>
 void doTheWork(float ***a, const float ***b, ComparatorT comparator)
 {
     for(int i=0; i<1000; i++)
         for(int j=0; j<10000; j++)
             for(int k=0; k<10000; k++)
                 a[i][j][k] = comparator(b[i][j][k], 500);
 }

 ...
 // Usage.
 bool bSign;
 ...
 if (bSign) {
     doTheWork(a, b, std::greater<float>());
 } else {
     doTheWork(a, b, std::larger<float>());
 }
模板
void doTheWork(浮点***a、常量浮点***b、比较器)
{

对于(int i=0;i,正如许多人所说,最好将
if
语句移出循环(如果可能)。为了防止代码重复,可以使用函数指针,但如果有真正的调用,情况可能会更糟。如果
调用比简单的
if
调用成本更高。如果编译器可以内联它们,就可以了

您还可以通过以下方式使用模板元编程(本例中为简单模板算法):

 template<typename ComparatorT>
 void doTheWork(float ***a, const float ***b, ComparatorT comparator)
 {
     for(int i=0; i<1000; i++)
         for(int j=0; j<10000; j++)
             for(int k=0; k<10000; k++)
                 a[i][j][k] = comparator(b[i][j][k], 500);
 }

 ...
 // Usage.
 bool bSign;
 ...
 if (bSign) {
     doTheWork(a, b, std::greater<float>());
 } else {
     doTheWork(a, b, std::larger<float>());
 }
模板
void doTheWork(浮点***a、常量浮点***b、比较器)
{

对于(inti=0;i为什么不这样使用它

  a[i][j][k] = (bSign == (b[i][j][k] > 500)) && (b[i][j][k] != 500);

你为什么不那样使用它

  a[i][j][k] = (bSign == (b[i][j][k] > 500)) && (b[i][j][k] != 500);

我不明白操作符重载是如何摆脱分支的。1)你不能改变语言。为int重载操作符是不可能的。2)bSign的值只有在运行时才知道。运算符重载应该如何工作,因为这发生在编译时。@CinCout:
a
大概是a
bool[1000][10000][10000]
。一个优秀的优化编译器会注意到bSign是一个循环不变量,并将其从最里面的循环中删除。我希望这段代码能够实际运行的机器,至少有500 GB的内存。在我的家用计算机上,如果我添加了一个更大的硬盘,这将永远无法运行,因为从d加载/写入虚拟内存isk。我不明白运算符重载是如何摆脱分支的。1)您不能更改语言。为int重载运算符是不可能的。2)bSign的值只有在运行时才知道。运算符重载应该如何工作,因为这是在编译时发生的。@CinCout:
a
大概是一个
bool[1000][10000][10000]
。一个不错的方法