C++ 编译器无法在Vector_const_迭代器和Vector_迭代器之间“转换”,即使这两种方法都可用
我试图围绕std::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
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 tbackwards_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 tbackwards_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,但没有迹象表明它真的会发生。不过,还是要感谢您提供了一个全面的答案和更多的弹药来推动新功能!