我的整个故事都是关于我那令人沮丧的旅程,即发现我从一个函数返回的无序地图实际上并不是RVO,即使我确定它在更早的时候它并不相关。有没有办法检查RVO是否被应用?
有没有办法检查RVO是否在任何给定的函数中发生?或者像一个do的列表,不要遵循以获得我期望的结果?
我的整个故事都是关于我那令人沮丧的旅程,即发现我从一个函数返回的无序地图实际上并不是RVO,即使我确定它在更早的时候它并不相关。有没有办法检查RVO是否被应用?
有没有办法检查RVO是否在任何给定的函数中发生?或者像一个do的列表,不要遵循以获得我期望的结果?
是的。为你的类的生命周期方法创建挂钩:
#include <iostream>
struct A{
A()
{ std::cout<<"Ctor\n"; }
A(const A& o)
{ std::cout<<"CCtor\n"; }
A(A&& o)
{ std::cout<<"MCtor\n"; }
~A()
{ std::cout<<"Dtor\n"; }
private:
int vl_;
};
A getA(){
A a;
return a;
}
int main(){
A b = getA();
return 0;
}
现在视网膜静脉阻塞,b为同一个对象在getA
a
所以你只能看到
Ctor
Dtor
可以抑制视网膜静脉阻塞,例如,通过添加附加的返回点:
return a;
return A{a};
或移动:
return std::move(a);
然后你会看到:
Ctor
Mctor
Dtor
Dtor
您可以验证RVO在所有地方重要的是要你的地方使用:
template<typename T>
struct force_rvo: T {
force_rvo() {}
using T::T;
force_rvo(const force_rvo &);
force_rvo(force_rvo &&);
};
force_rvo<std::map<int, int>> f() {
force_rvo<std::map<int, int>> m;
m[17] = 42;
return m;
}
int main() {
auto m = f();
return m[42];
}
的force_rvo
型假装可拷贝和可移动的,否则编译器会拒绝return m
。但是,如果其中任何一个被实际使用,链接器将会失败并告诉你发生了什么。包装是零成本,但要求在调用方和实现方都使用它,这可能不是很方便。
您检查生成的汇编代码?我不认为你可以从编译器请求这些信息。 – Borgleader
@Borgleader,不是每个人都能理解汇编: - )... – WhiZTiM
@WhiZTiM:不是每个人都能理解C++,但是这里我们是 –