4

ファンクターやイニシャライザーをコピーするとどうなるかについて少し混乱しています。次のコードでは、オブジェクトを常にコピー/移動すると思いましたが、それがSegfaultsであるかどうかは関係ありません。私は何か間違ったことをしているようですが、私の間違った仮定が何であるかをまだ理解していません。不思議なことに、cppreference.comで、コピーまたは移動コンストラクターが見つからなかったinitializer_listので、これらの場合に実際に何が起こるのだろうかと思います。

#include <string>
#include <vector>
#include <functional>
#include <iostream>

std::initializer_list<std::function<std::string()>> getInitializer() {
  return {
    []() -> std::string {
      return "If";
    }
  };
}

int main() {
    std::function<int(std::string)> func;
    {
        auto init = getInitializer();

        func = [init](std::string text) -> int {
            std::vector<std::function<std::string()>> vec(init);

            for( auto& el : vec ) {
                std::cout << el();
            }
            std::cout << text << std::endl;
            return 5;
        };
    }

    return func(" you see this - the world is all right!");
}
4

1 に答える 1

7

私はsの経験はあまりありませんが、標準では、配列へのポインタのペアであるかのようinitializer_listにanの実装を提案しているようです。initializer_listのリストにgetInitializer自動有効期間があり、それをサポートする配列も同様です。存在しなくなった配列へのポインタのペアを返すことになります。

この規格の関連セクションは、8.5.4[decl.init.list]の項目5および6です。

5.-タイプのオブジェクトは、実装がタイプのN個の要素のstd::initializer_list<E>配列を割り当てたかのようにイニシャライザーリストから構築されます。ここで、Nはイニシャライザーリスト内の要素の数です。その配列の各要素は、初期化子リストの対応する要素でコピー初期化され、オブジェクトはその配列を参照するように構築されます。要素のいずれかを初期化するためにナローイング変換が必要な場合、プログラムの形式が正しくありません。Estd::initializer_list<E>

initializer_list6.-配列の存続期間はオブジェクトの存続期間と同じです。


したがって、特定のケースでは、実装はこれとほぼ同等になります。

std::initializer_list<std::function<std::string()>> getInitializer() {
  std::function<std::string()> __a[1] = {
    []() -> std::string {
      return "If";
    }
  };
  return std::initializer_list<std::function<std::string()>>(__a, __a+1);
}
于 2012-06-24T01:41:43.150 に答える