OpenCV справляется с присвоением константной ссылки? - PullRequest
5 голосов
/ 01 декабря 2010

Я наткнулся на этот фрагмент кода в исходном коде 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", как и ожидалось.Проблема здесь в том, что

  1. любому, кто пишет подобный код, должны быть отрезаны руки
  2. в указанном выше источнике openCV, нет переопределения operator=, которое принимает Range параметры (Range связанные функции находятся чуть выше определения Vector, начиная со строки 1033)

Очевидно, что я что-то упускаю, так как исходный код openCV компилируется.Мой вопрос: что на самом деле происходит в строке r = Range(0, d.size());, которая делает его законным?

Ответы [ 3 ]

7 голосов
/ 02 декабря 2010

Я заметил, что резюме Vector - это шаблон класса. Поэтому, если этот метод класса никогда не создавался, ошибки компилятора не было. Я думаю, что если вы попробуете

Vector<int> a;
Vector<int> b(a, Range::all());

вы получите ошибку компилятора в этой подозрительной строке. Затем вы можете сообщить об этом как об ошибке в исходном коде OpenCV.

2 голосов
/ 02 декабря 2010

Моя теория заключается в том, что нарушающий код никогда не используется и, следовательно, никогда не создается.В конце концов, вектор - это шаблон.

Рассмотрим этот код:

template <class T>
class Vector
{
public:
   Vector()
   {
   }

   Vector(const Vector & x, const int & y)
   {
      y = 54;
   }
};
// template class Vector<float>;

void foo()
{
   Vector<float> v1;
//   Vector<float> v2(v1, 42);
}

GCC (версия 4.5.1) принимает это, но жалуется, как только вы добавите этот вызов во второй конструкторили явное создание шаблона.

0 голосов
/ 02 декабря 2010

Я предлагаю вам отправить его как отчет об ошибке здесь , или опубликовать свое сообщение в группе новостей OpenCV по адресу Y! G или непосредственно в списке разработчиков по адресу "opencvlibrary -devel@lists.sourceforge.net».

...