C++ 编译器无法在Vector_const_迭代器和Vector_迭代器之间“转换”,即使这两种方法都可用

C++ 编译器无法在Vector_const_迭代器和Vector_迭代器之间“转换”,即使这两种方法都可用,c++,visual-studio-2008,stdvector,const-iterator,reverse-iterator,C++,Visual Studio 2008,Stdvector,Const Iterator,Reverse Iterator,我试图围绕std::vector创建一个小包装器类来表示多项式的系数。调用方需要能够遍历系数,但我不想公开底层实现 使用所描述的模式和其他地方,我尝试传递迭代器,如下所示: typedef std::vector<unsigned char> charVec; class gf255_poly { public: // Constructors and Polynomial-y Functions // ... // I

我试图围绕std::vector创建一个小包装器类来表示多项式的系数。调用方需要能够遍历系数,但我不想公开底层实现

使用所描述的模式和其他地方,我尝试传递迭代器,如下所示:

typedef std::vector<unsigned char> charVec;

class gf255_poly
{
    public:

        // Constructors and Polynomial-y Functions

        // ...

        // Iterators to go from high to low degree

        charVec::const_reverse_iterator h2l_begin() const { return p.rbegin(); };
        charVec::const_reverse_iterator h2l_end()   const { return p.rend(); };
        charVec::reverse_iterator       h2l_begin() { return p.rbegin(); };
        charVec::reverse_iterator       h2l_end()   { return p.rend(); };

        // Iterators to go from low to high degree

        charVec::const_iterator l2h_begin() const { return p.begin(); };
        charVec::const_iterator l2h_end()   const { return p.end(); };
        charVec::iterator       l2h_begin() { return p.begin(); };
        charVec::iterator       l2h_end()   { return p.end(); };

    protected:
        std::vector<unsigned char> p;
};
虽然这看起来很简单,但类型有问题。Visual Studio在for循环行中给了我这个错误,我似乎无法解释:

error C2664: 'std::_Revranit<_RanIt,_Base>::_Revranit(_RanIt)' : cannot convert parameter 1 from 'std::_Vector_const_iterator<_Ty,_Alloc>' to 'std::_Vector_iterator<_Ty,_Alloc>'
我不理解这个消息-我提供了返回迭代器和常量迭代器的方法。为什么编译器不能在它们之间进行选择

这个问题隐含的是,这是否是一个很好的隐藏细节的策略,因为调用者仍然需要处理这些std::vector类型,我希望答案也能解决这个问题。

poly是一个const对象,所以h2l\u begin将返回一个const\u reverse\u迭代器。您已经将next_coef声明为反向迭代器,并且不能将常量迭代器分配给迭代器。要么将next_coef更改为const_reverse_迭代器,要么使用auto在for循环中声明它

for (auto next_coef = poly.h2l_begin(); next_coef != poly.h2l_end(); ++next_coef)
poly是一个常量对象,因此h2l_begin将返回一个常量反向迭代器。您已经将next_coef声明为反向迭代器,并且不能将常量迭代器分配给迭代器。要么将next_coef更改为const_reverse_迭代器,要么使用auto在for循环中声明它

for (auto next_coef = poly.h2l_begin(); next_coef != poly.h2l_end(); ++next_coef)
接下来是一个反向迭代器。h2l_开始返回什么

保利是一家:

常数gf255_多边形。让我们看看h2l_begin的覆盖:

有两个重载。只有一个是有效的,因为poly是常量,这就是:

// Performs polynomial evaluation in GF(2^8)
unsigned char gf255_poly_eval(const gf255_poly &poly, unsigned char x) const
{
    unsigned char fx = poly.coefHigh(); // Initialize with coef of highest degree term

    // Use Horner's method with consecutively factored terms:
    // x^3 + 2x^2 + 3x + 4 -> (((1x + 2)x + 3)x + 4)

    charVec::reverse_iterator next_coef;

    for (next_coef = poly.h2l_begin(); next_coef != poly.h2l_end(); next_coef++)
        fx = gf255_mul(fx, x) ^ *next_coef; // Recall ^ is addition in GF 2^8

    return fx;
}
charVec::const_reverse_iterator h2l_begin() const { return p.rbegin(); };
因此poly.h2l_begin返回一个charVec::const_reverse_迭代器

无法将charVec::const\u reverse\u迭代器转换为charVec::reverse\u迭代器,因为charVec::const\u reverse\u迭代器允许修改正在迭代的对象,而charVec::reverse\u迭代器不允许

简而言之,因为poly是const,所以您承诺不会修改它。然后使用可以修改它的类型对它进行迭代。所以你得到了一个类型错误

第二,顺便说一句,除了转换运算符T,编译器从不根据返回类型在函数之间进行选择。如果将非常量多边形存储在常量反向迭代器中,则仍然可以调用反向迭代器h2l\U begin。反向迭代器将转换为常量反向迭代器

首先要做的是升级到C++11。这是2016年

其次,我将编写一个范围,它存储一个迭代器范围,并根据迭代器运算符[]的随机访问性、大小等条件公开开始和结束。还将删除\u frontsize\t和front and empty以及

然后我将编写array_view:range_it,它表示一系列连续的Ts,其中包含来自容器的隐式ctor,这些容器具有T*C::data方法、原始C数组和T*,size_T

最后,我将编写backwards\u t和backwards函数,它获取一个range\u t并返回一个range\u t>

现在,我的gf255_多边形具有以下特征:

backwards_t< array_view< unsigned char > > h2l();
backwards_t< array_view< unsigned char const > > h2l() const;
array_view< unsigned char > l2h();
array_view< unsigned char const > l2h() const;
这很好

接下来是一个反向迭代器。h2l_开始返回什么

保利是一家:

常数gf255_多边形。让我们看看h2l_begin的覆盖:

有两个重载。只有一个是有效的,因为poly是常量,这就是:

// Performs polynomial evaluation in GF(2^8)
unsigned char gf255_poly_eval(const gf255_poly &poly, unsigned char x) const
{
    unsigned char fx = poly.coefHigh(); // Initialize with coef of highest degree term

    // Use Horner's method with consecutively factored terms:
    // x^3 + 2x^2 + 3x + 4 -> (((1x + 2)x + 3)x + 4)

    charVec::reverse_iterator next_coef;

    for (next_coef = poly.h2l_begin(); next_coef != poly.h2l_end(); next_coef++)
        fx = gf255_mul(fx, x) ^ *next_coef; // Recall ^ is addition in GF 2^8

    return fx;
}
charVec::const_reverse_iterator h2l_begin() const { return p.rbegin(); };
因此poly.h2l_begin返回一个charVec::const_reverse_迭代器

无法将charVec::const\u reverse\u迭代器转换为charVec::reverse\u迭代器,因为charVec::const\u reverse\u迭代器允许修改正在迭代的对象,而charVec::reverse\u迭代器不允许

简而言之,因为poly是const,所以您承诺不会修改它。然后使用可以修改它的类型对它进行迭代。所以你得到了一个类型错误

第二,顺便说一句,除了转换运算符T,编译器从不根据返回类型在函数之间进行选择。如果将非常量多边形存储在常量反向迭代器中,则仍然可以调用反向迭代器h2l\U begin。反向迭代器将转换为常量反向迭代器

首先要做的是升级到C++11。这是2016年

其次,我将编写一个范围,它存储一个迭代器范围,并根据迭代器运算符[]的随机访问性、大小等条件公开开始和结束。还将删除\u frontsize\t和front and empty以及

然后我将编写array_view:range_it,它表示一系列连续的Ts,其中包含来自容器的隐式ctor,这些容器具有T*C::data方法、原始C数组和T*,size_T

最后,我将编写backwards\u t和backwards函数,它获取一个range\u t并返回一个range\u t>

没有 w my gf255_poly具有以下功能:

backwards_t< array_view< unsigned char > > h2l();
backwards_t< array_view< unsigned char const > > h2l() const;
array_view< unsigned char > l2h();
array_view< unsigned char const > l2h() const;
这很好。

更改此选项:

charVec::reverse_iterator next_coef;
为此:

charVec::const_reverse_iterator next_coef;
您可以看到:poly是对gf255_poly对象的常量引用,表示对poly.h2l_begin的请求;在重载解析期间,将首选该函数的const限定版本

更好的是,使用自动

如果仍然必须将迭代器保持在for循环初始值设定项之外,则可以将初始化移到外部:

auto next_coef = poly.h2l_begin()
for (; next_coef != poly.h2l_end(); next_coef++)
    fx = gf255_mul(fx, x) ^ *next_coef; // Recall ^ is addition in GF 2^8
更改此项:

charVec::reverse_iterator next_coef;
为此:

charVec::const_reverse_iterator next_coef;
您可以看到:poly是对gf255_poly对象的常量引用,表示对poly.h2l_begin的请求;在重载解析期间,将首选该函数的const限定版本

更好的是,使用自动

如果仍然必须将迭代器保持在for循环初始值设定项之外,则可以将初始化移到外部:

auto next_coef = poly.h2l_begin()
for (; next_coef != poly.h2l_end(); next_coef++)
    fx = gf255_mul(fx, x) ^ *next_coef; // Recall ^ is addition in GF 2^8

不幸的是,C++11目前不是一个选项。整个开发团队都希望升级到VS,但没有迹象表明它真的会发生。不过,还是要感谢您提供了一个全面的答案和更多的弹药来推动新功能!不幸的是,C++11目前不是一个选项。整个开发团队都希望升级到VS,但没有迹象表明它真的会发生。不过,还是要感谢您提供了一个全面的答案和更多的弹药来推动新功能!