【问题标题】:Supporting "for each" on custom const native C++ container class在自定义 const 本机 C++ 容器类上支持“for each”
【发布时间】:2012-12-10 04:26:00
【问题描述】:

我想实现一个简单的原生 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 是什么?谢谢!

【问题讨论】:

    标签: c++ foreach constants containers native-code


    【解决方案1】:

    您的用例对我来说似乎有点奇怪,因为您写下来的 C++ 中的每个构造都没有。 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';
        }
    }
    

    【讨论】:

    • 感谢您抽空弗拉德。我没有提到“for each”似乎是最近微软编译器特有的语法糖(我不关心可移植性)。如果 VS2010 支持您描述的 C++11 语法,我很乐意使用它 - 我现在不在开发机器上,但我假设 for( const int p : array ) 也可以工作?尽管如此,我还是很好奇为什么“for each”对我不起作用,而且似乎找不到任何可以提供一些启示的好的文档。
    • @beau 哦,我用谷歌搜索过,似乎是 VS 2005 中引入的非标准微软特定结构。我不能说太多,因为我已经多年没有使用 MS 编译器了。 . 但是 VS 2010 绝对支持基于标准的 C++11 范围,但您可能必须在项目设置中选择它。抱歉在这里没用,我试过了;)
    • @beau:基于 C++11 范围的 for 循环仅在 VS 2012 中添加。
    • @Blastfurnace:书呆子。所以我最初的问题并没有失去任何重要性(对我来说)。
    猜你喜欢
    • 2015-06-05
    • 2011-08-03
    • 1970-01-01
    • 1970-01-01
    • 2020-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多