理解关于c ++ 11的隐藏规则 [英] Understanding eliding rules with regard to c++11

查看:110
本文介绍了理解关于c ++ 11的隐藏规则的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在测试与右值引用和移动语义,并希望确保我理解,当一个副本应该被省略,当它应该跟随移动语义。

I have been testing with rvalue references and move semantics and want to make sure I understand when a copy should be elided and when it should follow move semantics.

给予以下

class NRVCA
{
public:
    NRVCA(int x):
    {}
    NRVCA(const NRVCA & Rhs)
    {}    
    NRVCA& operator=(const NRVCA& dref)
    {}          
};

NVCRA GetATemp()
{       
   return NVCRA(5);
} 

NVCRA GetACopy()
{
   NVCRA ret(5);
   ...
   return ret;  
}

int main()
{ 
    //This call will be elided allays and invoke the single param constructor 
    NVCRA A = GetATemp();
    //This call will be a traditional copy the complier may elide this 
    // if so the work will be done inline 
    NVCRA B = GetACopy();

}

在这种情况下,移动语义不起作用,从C ++ 03在c ++ 11是,而不是允许编译器elide他们需要elide。

In this case move semantics play no part and the only difference from C++03 in c++11 is that rather than the compiler being allowed to elide they are required to elide.

所以
问题1.在什么情况下,我保证复制构造函数将被或不会被省略。

So Question 1. Under what cases am I guaranteed a copy constructor will or will not be elided.

问题2.是否有办法强制编译器不要删除。

Question 2. Is there a way to force the compiler to not elide.

问题3.有什么逻辑原因我不想让编译器这样做,假设您具有逻辑一致的复制操作。

Question 3. Is there any logical reason why I would not want the compiler to do so, assuming that you have logically consistent copy operations.

问题4.如果我定义了一个移动构造函数,移动将发生在副本不被舍弃的情况下。这应该影响我的类设计。

Question 4. If I define a move constructor, a move will occur in cases where the copy is not elided anyway. Should this effect my design of classes.

推荐答案


  1. Eliding副本和移动始终是可选优化,关于什么时候会做。 Elision不同于编译器选择move over copy。

  1. Eliding copies and moves is always an optional optimization and the standard offers no guarantees on when it will be done. Elision is different from the compiler choosing move over copy. The language guarantees when move construction or move assignment is chosen according to its normal overload resolution rules.

一些编译器提供一个标志来关闭elision。 gcc和clang有 -fno-elide-constructors 。 MSVC没有一个特定的选项,但禁用优化可以避免一些错误(但有些不能被关闭,无论什么,例如 Foo x = 1;

Some compilers offer a flag to turn elision off. gcc and clang have -fno-elide-constructors. MSVC does not have a specific option, but disabling optimization may avoid some elisions (but some can't be turned off no matter what, such as the copy in Foo x = 1;)

我不知道有任何理由不要在生产版本中删除副本/动作。

I don't know of any reason not to elide copies/moves in production builds.

有些人建议在返回重类时不要依赖返回值优化,因为RVO不能保证。我个人我只是验证我的编译器是好的,并继续。现在对象可以移动,你不再需要担心编译器是否支持这样的优化,因为即使它不会,你仍然会得到移动,而不是副本。

Some people had recommended not relying on the 'return value optimizaiton' when returning 'heavy' classes, because RVO isn't guaranteed. Personally I just verified that my compilers were good about it and went ahead with it. Now that objects can be moved you no longer need to worry about whether a compiler supports such optimizations, because even if it doesn't you'll still get moves instead of copies.

这篇关于理解关于c ++ 11的隐藏规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆