4

Container個々の配列にデータを格納するカスタム コンテナーを作成したいと考えています。ただし、コンテナーの反復を容易にするために、オーバーロードによってコンテナーの「ビュー」を提供し、実際のコンテナーへの参照としてすべてのコンテナー変数を保持operator[]する単一の構造体を返します。Valueこれは私がこれまでに得たものです:

#include <iostream>
using namespace std;

struct Value {
  Value(int& data) : data_(data) { }
  int& data() { return data_; }
  int& data_;
};

struct Container {
  Value makeValue(int i) { return Value(data_[i]); } // EDIT 1
  Value&& operator[](int i) {
    // return std::forward<Value>(Value(data_[i]));
    return std::forward<Value>(makeValue(i)); // EDIT 1
  }

  int data_[5] = {1, 2, 3, 4, 5};
};

int main(int, char**)
{
  // Create and output temporary
  Container c;
  cout << c[2].data() << endl; // Output: 3 - OK!

  // Create, modify and output copy
  Value v = c[2];
  cout << v.data() << endl; // Output: 3 - OK!
  v.data() = 8;
  cout << v.data() << endl; // Output: 8 - OK!

  // Create and output reference
  Value&& vv = c[2];
  cout << vv.data() << endl; // Output: 8 - OK, but weird:
                             // shouldn't this be a dangling reference?
  cout << vv.data() << endl; // Output: 468319288 - Bad, but that's expected...
}

上記のコードは、私が知る限り機能していますが、ここで最善のアプローチを使用するかどうか疑問に思っています:

  1. Value不必要なコピーを避けたい場合、右辺値参照として返すのは正しいですか?
  2. の使い方はstd::forward正しいですか?std::move(この例では両方とも機能します)または他のものを使用する必要がありますか?
  3. コンパイルされたプログラムの出力は、コメントに記載されています。Value&& vv...宣言する(または構文的に禁止する)ときにダングリング参照を回避する方法はありますか?

編集1

Valueインスタンスがメソッドで直接作成されるのではoperator[]なく、別のヘルパー関数で作成されるように、ソース コードに小さな変更を加えました。それは何かを変えるでしょうか?makeValue(int i)示されているようにメソッドを使用する必要がありますか、それともここでstd::move/を使用する必要がありstd::forwardますか?

4

2 に答える 2