0

私は、通常std ::vector<>のタイトラッパーとして実装されるいくつかのデータ型クラスを定義するライブラリを使用しています。タイプ階層は数層の深さであり、ほとんどの場合、精巧なコンストラクターを追加するだけです。

私の問題:基本クラスはそのstd :: vectorをprivate(これは問題ありません)として定義しますが、アクセサメソッドをconstとして追加するだけです。派生クラスはそれにアクセスすることさえできません。ライブラリは次のようになります(わかりやすくするために短縮されています)。

template <class T> class BaseList
{
public:
    BaseList (const T data0) : data_ (1) { 
       data_[0] = data0; }

    const T & operator[] (const size_t nr) const { 
       // does out off bounds check here       
       return data_[nr]; }

private:
    std::vector<T> data_;
}

class FancyClass : public BaseList<SomeEnumType>
{
public:
    FancyClass (const SomeOtherEnumType data0) 
        : BaseList<SomeEnumType> ( static_cast<SomeEnumType> (data)) 
        {}
}

今私が見ているように、constの定義は完全に偽物です。ベクトルが実際に一定であることに依存する内部メソッドはありません。外部コードでも同様です。

私がしたいのはこれだけです:

strukt MyType {
    FancyClass myData;
    bool otherData;
}

int main() {
    MyType storage = {FancyClass(0), false};

    storage.myData[0] = 5;
}

もちろん、これは恒常性のために機能しません。(「読み取り専用の場所の割り当て」)

完全に私の側の責任で:この構造を書き込み可能にするために私ができるconst_castの魔法はありますか?私が知っている他の唯一の可能性は、コード内の型階層を完全に複製することですが、それでも、ライブラリコードをインターフェイスするたびに呼び出す多くのキャストまたはtoFancyClass()関数が残ります。

何か案は?ありがとう!

(ライブラリのコード品質についてコメントしないでください。それを変更できれば、この質問はしません...)

4

3 に答える 3

1

今私が見ているように、constの定義は完全に偽物です。ベクトルが実際に一定であることに依存する内部メソッドはありません。外部コードでも同様です。

メソッドのconst修飾子は、それが定数であるベクトルに依存していることを意味するものではありません。これは、メソッドがオブジェクトの状態を変更しないことを意味します。以下のコードがコンパイルされるように追加されています。

void f(const FancyClass a)
{
    cout<<a[0];
}

上記のコードは、[]メソッドにconst修飾子がないとコンパイルできません。

とにかく、以下はうまくいくはずです

SomeEnumType & r = const_cast<SomeEnumType &>(storage.myData[0]);

r = b;

タイプbはどこですかenumSomeEnumType

ただし、storageオブジェクトが実際にconstオブジェクトである場合は、未定義の動作につながります。

于 2012-12-03T13:47:37.847 に答える
1

最も簡単なのは、非定数バージョンのoperator[]を追加することです。それ以外の場合は、を使用して定数をキャストすることでUBを引き起こす可能性がありますconst_cast

あなたはこのように恒常性を捨てることができます:

int main() {
    MyType storage = {FancyClass(0), false};

    const_cast< SomeEnumType& >( storage.myData[0] ) = 5;
}
于 2012-12-03T13:30:49.303 に答える
0

通常、operator []は、可変バージョンとconstバージョンのペアで提供されます。(参照:演算子のオーバーロード

もちろん、const_castベースのソリューションもありますが、未定義の動作が含まれます(constnessをキャストした後に値を変更することはできません!)

于 2012-12-03T13:33:47.827 に答える