17

私はその質問を見つけることができませんでした、そしてそれは私が直面している実際の問題です。

std::vector<unsigned char>ファイルの内容全体を含むファイル読み込みユーティリティがあります。ただし、処理関数にはの連続配列が必要ですchar(これは変更できません。これはライブラリ関数です)。とにかく処理関数を使用しているクラスはデータのコピーを格納するので、として格納したいと思いvector<char>ます。これがもう少しわかりやすいコードです。

std::vector<unsigned char> LoadFile (std::string const& path);

class Processor {
    std::vector<char> cache;
    void _dataOperation(std::vector<char> const& data);

public:
    void Process() {
        if (cache.empty())
            // here's the problem!
            cache = LoadFile("file.txt");

        _dataOperation(cache);
    }
};

(明らかに)適切な変換がないため、このコードはコンパイルされません。ただし、一時ベクトルが同じ量のメモリ(IOW sizeof(char) == sizeof(unsigned char))を占有することは確かです。

素朴な解決策は、一時的なコンテンツを繰り返し処理し、すべてのキャラクターをキャストすることです。通常の場合、operator= (T&&)が呼び出されることを私は知っています。

私の状況では、ASCII文字のみを読み取ると確信しているため、変換を再解釈しても安全です。_dataOperationとにかく他のキャラクターは捕まるでしょう。

だから、私の質問は:コピーを伴わない方法で一時的なベクトルを適切かつ安全に変換する方法は?

それが不可能な場合は、安全でない非コピーよりも安全なコピー方法をお勧めします。またはLoadFileを返すように変更することもできます。vector<char>vector<unsigned char>

4

1 に答える 1

8

C ++ 11では、[basic.lval]p10は次のように述べています。

プログラムが次のタイプのいずれか以外のglvalueを介してオブジェクトの保存された値にアクセスしようとした場合、動作は未定義です。

  • ..。
  • char型またはunsignedchar型。

(正確な場所は他のバージョンのC ++では異なる場合がありますが、意味は同じです。)

つまりvector<unsigned char> cache、範囲を使用して、を取得し、そのコンテンツにアクセスできることを意味します[reinterpret_cast<char*>(cache.data()), reinterpret_cast<char*>(cache.data()) + cache.size())。(@Kerrek SBがこれについて言及しました。)

の戻り型に一致するようvector<unsigned char>にを格納し、実際に(aとサイズを意味する)の配列をとる場合は、引数をに渡すときにキャストできます。ProcessorLoadFile_dataOperation()charconst char*_dataOperation()

ただし、具体的にを_dataOperation()取り、vector<char>を保存するvector<unsigned char> cacheと、それを渡すことはできませんreinterpret_cast<vector<char>&>(cache)。(つまり、@AndréPuelは完全に間違っています。彼の言うことを聞かないでください。)これはエイリアシング規則に違反し、コンパイラは午前2時に顧客を怒らせようとします。(そして、このバージョンのコンパイラーがそれを管理しない場合、次のバージョンは試行を続けます。)

1つのオプションは、前述のように、テンプレートを作成LoadFile()して、必要なタイプのベクトルを返す(または入力する)ことです。もう1つは、結果をコピーすることです。この場合も、簡潔なバージョンはreinterpret_castソースベクトルの.data()です。[basic.fundamental] p1は、「文字タイプの場合、オブジェクト表現のすべてのビットが値表現に参加する」と述べています。つまり、これでデータが失われることはありませんreinterpret_castunsigned charのビットパターンがトラップを引き起こさないという確固たる保証はありませんreinterpret_cast'edchar、それを行う最新のハードウェアやコンパイラについては知りません。

于 2013-05-20T00:54:01.540 に答える