Я наткнулся на этот фрагмент кода в исходном коде openCV ( cxoperations.hpp , строка 1134, в определении класса Vector
):
Vector(const Vector& d, const Range& r)
{
if( r == Range::all() )
r = Range(0, d.size());
// some more stuff...
}
Обратите внимание, чтокласс Vector
не имеет члена данных с именем r
(и действительно, идентификатор r
встречается только в еще одном месте во всем определении класса, как параметр в другом методе).Очевидно, что здесь есть присвоение ссылки const
.
Я попытался воспроизвести минимальный пример:
#include <iostream>
class Foo
{
public:
int _a;
Foo(int a) : _a(a) {}
};
int main()
{
Foo x(0);
const Foo& y = x;
printf("%d\n", y._a);
y = Foo(3);
printf("%d\n", y._a);
}
Это, конечно, не компилируется: g ++ даетошибка
test.cpp:15: error: passing `const Foo' as `this' argument of `Foo& Foo::operator=(const Foo&)' discards qualifiers
Единственный способ заставить его работать - переопределить operator=
следующим образом:
#include <iostream>
class Foo
{
public:
int _a;
Foo(int a) : _a(a) {}
Foo& operator=(Foo rhs) const
{
Foo& tmp = const_cast<Foo&>(*this);
tmp._a = rhs._a;
return const_cast<Foo&>(*this);
}
};
int main()
{
Foo x(0);
const Foo& y = x;
printf("%d\n", y._a);
y = Foo(3);
printf("%d\n", y._a);
}
Это компилирует и печатает "0 3", как и ожидалось.Проблема здесь в том, что
- любому, кто пишет подобный код, должны быть отрезаны руки
- в указанном выше источнике openCV, нет переопределения
operator=
, которое принимает Range
параметры (Range
связанные функции находятся чуть выше определения Vector
, начиная со строки 1033)
Очевидно, что я что-то упускаю, так как исходный код openCV компилируется.Мой вопрос: что на самом деле происходит в строке r = Range(0, d.size());
, которая делает его законным?