我有一些这样的代码,其中 vec 是某种 vector 类:
Vec Vec::choose(const Vec& ifPositive, const Vec& ifNegative) const {
Vec out(mSize);
for(int index = 0; index < mSize; ++index) {
if(mData[i] > 0)
out[i] = ifPositive[i];
else
out[i] = ifNegative[i];
}
return out;
}
现在这段代码总体上可以正常工作,但是如果函数的左侧是参数之一,就会有一些不必要的构造函数/析构函数调用:
curVal = trigger.choose(posVal, curVal); // construct is called in choose, then old curVal is destroyed
有没有什么方法可以改善/避免这种情况,比如如果编译器看到函数的左侧是参数之一,它会运行不同的代码?
编辑: 这是一些示例代码:http://ideone.com/nPUK3h
我想知道是否可以省略最后一个 (4.) 构造。 稍后我会在家里用一些更复杂的优化来编译它。
编辑2: 如果我引入以下附加功能,我可以避免附加构造:
Vec& Vec::setNegative(Vec& target, const Vec& ifNegative) const {
for(int index = 0; index < mSize; ++index) {
if(mData[index] <= 0)
target[index] = ifNegative[index];
}
return target;
}
因此,如果选择函数的 lhs 与第一个参数相同,则会产生相同的输出,但是如果 lhs 是另一个 vector ,我想改为获取一个新 vector 。
是否有某种方法可以通过某种模板魔术或编译器技术在两者之间进行选择?
最佳答案
IIRC,RVO 允许编译器在接收对象的位置构造返回值,但在这种情况下,在调用中使用对该对象的引用,即在参数被构造之前构造返回值用过。
所以我可以看到这将如何击败 RVO。不过,我不明白为什么它会打败移动。
关于c++ - 如果它是参数并且可以修改,则避免构造新对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17339458/