6

std::vector<int> メンバーを持つクラスと、そのベクターへの const 参照を返すメンバー関数があります。

class demo {
public:
    //...

    const std::vector<int> & test() const {
        return iv;
    }

private:

    std::vector<int> iv;
};

メンバーの型を、コンテナー型のような別の配列に変更して、機能が十分でメモリ フットプリントが小さいものに変更する予定です (例: std::experimental::dynarray、std::unique_ptr<int[]>)。したがって、実際のコンテナーを const 参照として返すのではなく、要素へのビューを gsl::span<const int> として返すことをお勧めします。

class demo {
public:
    //...

    gsl::span<const int> test() const {
        return iv;
    }

private:

    std::vector<int> iv;
};

ただし、同じ未変更のベクターの 2 つのスパン インスタンスを使用して要素を反復処理できないため、const vector<int>& で機能するコードが壊れます。

demo d;

std::cout << (d.test().begin() == d.test().begin()) << "\n";
std::cout << (d.test().end() == d.test().end()) << "\n";

for( auto it = d.test().begin(), end = d.test().end(); it != end; ++it )
    std::cout << *it << "\n";

テスト it != end は決して失敗しないため、これは 0 0 を出力してからクラッシュします。範囲ベースの for ループはもちろん機能しますが、このループは有効であるため、期待どおりに機能する必要があります。私は、同じコンテナの同じ範囲からのすべてのスパンが等しいので、これらのスパンのいずれかのイテレータが比較できると予想していました(もちろん、コンテナは変更されていません)。確かに、そうではないのには十分な理由があります。

だから私の質問は、そのようなビューを呼び出し元に見えてはならないコンテナのような配列の要素に返す最良の方法は何ですか.

4

2 に答える 2