将构造函数转换为函数的返回值

时间:2013-10-05 16:35:39

标签: c++ function constructor std rvo

是否可以使用转换构造函数而不是复制构造函数来从函数返回对象,即使没有进化的RVO(假设编译器不支持任何此类优化)?问题的关键是C ++标准告诉我什么,有人可以告诉我吗?我得到了gcc并编写了下面的代码,并在评论中提出了几个问题。



    class A
    {
    public:
        A(int) {};
        A(int, int) {};

    private:
        A(const A &) = delete;
        A & operator = (const A &) = delete;
    };

    A foo(void)
    {// All the CEs below are all the same, which is 'using the deleted function 'A::A(const A&)''.
        //return(0); // Not compiled.
        //return(A(0)); // Not compiled. ok since the A isn't be copy-able.
        //return {0};  // Compiled. Is it a bug of the compiler?
        //return({0}); // Not compiled. What happened when returns in '()' implemented?
        //return 0;  // Not compiled. What happened when returns without '()' and '{}' implemented?
        //return ({0, 0}); // Not compiled.
        return {0, 0}; // Compiled. Realy??

    /*
      1. What are the differences in 'return 0', 'return {0}', 'return(0)' and 'return({0})'?
      2. Is it any possible to do conversion from source type object 'which is 'int' in this sample' to returning type of
    the function directly with only ONE constructor call even if the compiler has no any copying eliminating optimization
     but full compatibility with STD? Note that the function 'foo' here has no returning object accepter.
    */
    }

    int main(void)
    {
        foo(); // Note that there is no accepter of 'A' here, it's not discussing purpose at this topic of the post.
    }

    // compiling with the gcc ver. 4.8.1.

1 个答案:

答案 0 :(得分:2)

是的,如果使用braced-init-list初始化返回的对象,则在return语句中调用转换构造函数是完全有效的。

C ++ 11标准在6.6.3 [stmt.return]中说明了这一点:

  

表达式的值隐式转换为它出现的函数的返回类型。返回语句可能涉及构造和复制或移动临时对象(12.2)。 [注意:与return语句关联的复制或移动操作可能被省略或被视为rvalue,以便在重载中解决   选择一个构造函数(12.8)。 - end note ]带有 braced-init-list 的return语句初始化通过copy-list-initialization(8.5.4)从函数返回的对象或引用从指定的初始化列表中。 [示例:

std::pair<std::string,int> f(const char* p, int x) {
  return {p,x};
}
  

- 结束示例]

在其他注释掉的return语句中,您将创建一个临时对象,然后需要将其复制到返回的对象,这需要一个可访问的副本ctor。