2016-03-02 129 views
4

我的整个故事都是关于我那令人沮丧的旅程,即发现我从一个函数返回的无序地图实际上并不是RVO,即使我确定它在更早的时候它并不相关。有没有办法检查RVO是否被应用?

有没有办法检查RVO是否在任何给定的函数中发生?或者像一个do的列表,不要遵循以获得我期望的结果?

+1

您检查生成的汇编代码?我不认为你可以从编译器请求这些信息。 – Borgleader

+0

@Borgleader,不是每个人都能理解汇编: - )... – WhiZTiM

+3

@WhiZTiM:不是每个人都能理解C++,但是这里我们是 –

回答

3

是的。为你的类的生命周期方法创建挂钩:

#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为同一个对象在getAa所以你只能看到

Ctor 
Dtor 

可以抑制视网膜静脉阻塞,例如,通过添加附加的返回点:

return a; 
return A{a}; 

或移动:

return std::move(a); 

然后你会看到:

Ctor 
Mctor 
Dtor 
Dtor 
2

您可以验证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。但是,如果其中任何一个被实际使用,链接器将会失败并告诉你发生了什么。包装是零成本,但要求在调用方和实现方都使用它,这可能不是很方便。

相关问题