В моей библиотеке при переходе на версию STL из поставки VS2005 (с STLPort все в порядке)
полезли ошибки компиляции. Вот минимальный код, приводящий к ошибке
#include "stdafx.h"
#include <vector>
namespace mtr{
template<typename T>
class Argument
{
const T& arg_;
public:
Argument(T const& arg)
: arg_(arg)
{}
};
template<typename T, typename U>
class Expression
{
typedef Argument<T> Left;
typedef Argument<U> Right;
const Left left_;
const Right right_;
public:
Expression( const Left& left, const Right& right )
: left_(left), right_(right)
{}
};
struct Matrix
{
float p[3];
};
template<typename Left, typename Right>
inline Expression<Left, Right> operator + (Left const& a, Right const& b )
{
return Expression<Left, Right>(a, b);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<mtr::Matrix> v;
v.resize(2);
return 0;
}
Ошибка компиляции в недрах std::vector<>::resize, которая определена так:
void resize(size_type _Newsize, _Ty _Val)
{
if (size() < _Newsize)
_Insert_n(end(), _Newsize - size(), _Val);
else if (_Newsize < size())
erase(begin() + _Newsize, end());
}
Проблема в выражении begin() + _Newsize и заключается в том, что _Newsize имеет тип
size_type, а для итератора, возаращаемого begin() операция сложения определена так:
_Myt operator+(difference_type _Off) const
{ // return this + integer
_Myt _Tmp = *this;
return (_Tmp += _Off);
}
Что делает компилятор: он считает, что вместо преобразования size_type->difference_type [это преобразование unsigned int->int для того чтобы
вызвать operator+(difference_type _Off) const ] более подходящим являетя мой
шаблонный!! оператор Expression<Left, Right> operator + (Left const& a, Right const& b ),
который он и подставляет. Дальше все по плану: Expression<Left, Right> не возможно превести к std::vector<>::iterator, который требуется для вызова erase(...)
Вопрос 1. Почему компилятор лезет в мое пространство имен, проводя зависимый поиск, хотя аргументы в begin() + _Newsize к нему ни какого отношения не имеют?
Вопрос 2. Почему если внутри resize (для вызова begin() + _Newsize) требуется приведение типа разработчики на сделали это явно (это конечно если компилятор прав в первом вопросе)?
Вопрос 3. Что делать? Править исходник вектора не хочется.
ps: с STLPort все в порядке потому, что в векторе итератор это просто голый указатель. С ним у компилятора вопросов не возникает.