支持自定义 const 本机C++容器类的"for each"



我想实现一个简单的本机C++固定容量数组模板类,为方便起见,支持基于范围的"for each"语法,开销最小。

我在常量实例上支持它时遇到问题。

通过此实现:

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<> 如何正确处理这个问题? 谢谢!

您的用例对我来说似乎有点奇怪,因为在您写下它时,C++中没有每个结构。C++11 中引入了常规for和基于范围的for。我只能猜测您的真实用例是什么,但很可能编译器由于恒定正确性错误而抱怨。如果没有您尝试运行的真实代码,我无法真正确定您的错误。无论如何,下面是一个演示这两种用法的工作示例。希望对您有所帮助,但如果您有任何问题 - 请随时跟进,我会尝试解释。

#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';
    }
}

最新更新