2

進化した RVO がない場合でも、コピー コンストラクターではなく変換コンストラクターを使用して関数からオブジェクトを返すことは可能ですか (コンパイラーがそのような種類の最適化をサポートしていないとします)。質問のポイントは、C++ std が何を言っているのかということです。誰か教えてもらえますか? 私は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.

4

1 に答える 1

2

はい、波括弧初期化リストを使用して返されたオブジェクトを初期化する場合、return ステートメントで変換コンストラクターを呼び出すことは完全に有効です。

C++11 標準では、6.6.3 [stmt.return] で次のように述べられています。

式の値は、それが現れる関数の戻り値の型に暗黙的に変換されます。return ステートメントには、一時オブジェクト (12.2) の作成とコピーまたは移動が含まれる場合があります。[注: return ステートメントに関連付けられたコピーまたは移動操作は、省略されるか、コンストラクター (12.8) を選択する際のオーバーロード解決の目的で右辺値と見なされる場合があります。—終わりの注] 中括弧初期化リストを持つ return ステートメントは、指定された初期化子リストからのコピー リスト初期化 (8.5.4) によって、関数から返されるオブジェクトまたは参照を初期化します例:

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

終了例]

他のコメントアウトされたreturnステートメントでは、一時オブジェクトを作成し、それを返されたオブジェクトにコピーする必要があります。これには、アクセス可能なコピー ctor が必要です。

于 2013-10-05T16:49:55.290 に答える