4

シンプルなネイティブ C++ 固定容量配列テンプレート クラスを実装して、範囲ベースの "for each" 構文を便利にサポートし、オーバーヘッドを最小限に抑えたいと考えています。

const インスタンスでのサポートに問題があります。

この実装では:

template< class T, size_t Capacity >
class List
{
public:
    List() { mSize = 0; }

    const T* begin() const { return mItems; }
    const T* end() const { return mItems + mSize; }

    T* begin() { return mItems; }
    T* end() { return mItems + mSize; }

private:
    size_t mSize;
    T mItems[ Capacity ];
};

そしてこの使用法:

const List< int, 5 > myInts;
for each( const int myInt in myInts )
{
    continue;
}

次のエラーが表示されます。

error C2440: 'initializing' : cannot convert from 'const int *' to 'int *'
    Conversion loses qualifiers

この使用法は文句を言いません:

List< int, 5 > myInts;
for each( const int myInt in myInts )
{
    continue;
}

そして、この(望ましくない)実装は文句を言いません:

template< class T, size_t Capacity >
class List
{
public:
    List() { mSize = 0; }

    T* begin() const { return const_cast< List* >( this )->mItems; }
    T* end() const { return const_cast< List* >( this )->mItems + mSize; }

private:
    size_t mSize;
    T mItems[ Capacity ];
};

私が理解していないフードの下で何が起こっているのですか? これを適切に処理する std::vector<> についてはどうですか? ありがとう!

4

1 に答える 1

2

あなたが書き留めたように、C++には for each コンストラクトがないため、あなたのユースケースは私にとって少し奇妙に思えます。C++11 で導入された正規forおよび範囲ベースがあります。for私はあなたの実際のユースケースが何であるかを推測することしかできませんが、ほとんどの場合、const-correctness の間違いのためにコンパイラが文句を言います。あなたが実行しようとしている実際のコードがなければ、間違いを正確に特定することはできません。とにかく、以下は両方の使用法を示す実際の例です。お役に立てば幸いですが、ご不明な点がございましたら、お気軽にお問い合わせください。説明させていただきます。

#include <cstdlib>
#include <iostream>

template <typename T, std::size_t Capacity>
class List {
  public:
    List() : mSize(0) {}

    const T *begin() const { return mItems; }
    const T *end() const { return mItems + mSize; }

    T *begin() { return mItems; }
    T *end() { return mItems + mSize; }

    void add(int v)
    {
        // TODO: Check for out of range here...
        mItems[mSize++] = v;
    }

  private:
    size_t mSize;
    T      mItems[Capacity];
};

int main()
{
    /* const */ List<int, 10> array;

    array.add(1);
    array.add(11);
    array.add(15);
    array.add(3);

    // C++11 style (range-based for)
    for (int p : array) {
        std::cout << p << '\n';
    }

    // Pre C++11 style
    for (const int *from = array.begin(), *to = array.end(); from != to; ++from)
    {
        int p = *from;
        std::cout << p << '\n';
    }
}
于 2012-12-10T04:38:05.053 に答える