Проблема с конструкторами “no matching function for call to…”

271
30 июля 2017, 09:35

Пишу класс матриц и возникла проблема с конструкторами. В предпоследней строчке при вызове конструктора, принимающего на вход 3 переменные, компилятор выдает ошибку no matching function for call to 'Matrix<3u, 1u, float>::Matrix(Vec3f)'.

Вот код (я выкинул операторы, чтобы было проще найти ошибку):

#define temop2  template<size_t R1, size_t C1, size_t R2, size_t C2, class T>
#define temop1  template<size_t R, size_t C, class T>
#define vec_ini _Mat(vector<vector<T>> (R, vector<T> (C, 0.)))
#define x       _Mat[0][0]
#define y       _Mat[1][0]
#define z       _Mat[2][0]
template<size_t R, size_t C, class T> struct Matrix  
{
    Matrix (): vec_ini
    {}
    Matrix (T _x, T _y, T _z): vec_ini
    {
        _Mat[0][0] = _x;
        _Mat[1][0] = _y; 
        _Mat[2][0] = _z;
    }
    Matrix (T _x, T _y): vec_ini
    {
        _Mat[0][0] = _x;
        _Mat[1][0] = _y;
    }
    Matrix (Matrix<R, C, T>& v): vec_ini 
    { 
        *this = v; 
    }
    vector<T>& operator [] (const int i)
    {
        assert (i >= 0 && i < R);
        return _Mat[i];
    }
    Matrix<R, C, T>& operator = (Matrix<R, C, T> &m)
    {
        for(size_t i = R; i--; )
            for(size_t j = C; j--; )
                _Mat[i][j] = m[i][j];
        return *this;
    }
    vector<vector<T> > _Mat;
};
typedef Matrix<2, 1, float> Vec2f;
typedef Matrix<3, 1, float> Vec3f;
typedef Matrix<2, 1, int> Vec2i;
typedef Matrix<3, 1, int> Vec3i;
Vec3f m2v (Matrix<4, 1, float> m)
{
    return Vec3f (m[0][0]/m[3][0], m[1][0]/m[3][0], m[2][0]/m[3][0]);
}

Также, не знаю почему, ошибка пропадает, если убрать строку
Matrix (Matrix<R, C, T>& v): vec_ini { *this = v; }

Помогите, пожалуйста!

Answer 1

Ваш конструктор копирования требует на вход lvalue-ссылку на неконстантный объект (ака "неконстантная ссылка")

Matrix (Matrix<R, C, T>& v)

Вы же пытаетесь передавать туда временный объект

return Vec3f (m[0][0]/m[3][0], m[1][0]/m[3][0], m[2][0]/m[3][0]);

Неконстантная ссылка не может быть привязана к временному объекту. Поэтому вызвать вышеупомянутый конструктор копирования в данном контексте невозможно. Других подходящих конструкторов у вас нет. Возникает ошибка.

С чего это вдруг у вас параметр конструктора копирования (и оператора присваивания тоже) является неконстантной ссылкой? Почему вы убрали с ссылки константность?

Если убрать ваше корявое объявление конструктора копирования, то компилятор сгенерирует конструктор копирования для вашего класса самостоятельно. И у этого конструктора копирования параметр будет иметь правильный тип const Matrix &, т.е. этот конструктор копирования будет прекрасно вызваться в данном контексте. Поэтому ошибка и пропадает.

Тут возникает закономерный вопрос: учитывая, что ваш класс состоит просто из vector<vector<T> > _Mat;, зачем вы вообще писали конструктор копирования и оператор присваивания вручную? Чем вас не устроили неявные реализации, предоставляемые компилятором?

READ ALSO
Тестирование Travis ci, cmake сборка, c++

Тестирование Travis ci, cmake сборка, c++

Добрый деньПроблема при сборке в travis-ci

317
Точка строго внутри четырехугольника

Точка строго внутри четырехугольника

Дан вектор длины 4 точек выпуклого четырехугольника в произвольном порядке, а также произвольная точка PНеобходимо определить, лежит ли эта...

276
Magnific popup, как задать разный бэкграунд?

Magnific popup, как задать разный бэкграунд?

Допустим нужно для разных модальных окон задать разный цвет бэкграундаПо умолчанию для класса

394
Вставка после X параграфов

Вставка после X параграфов

Салют! Есть такой код для вставки Гугла после 3-го параграфа

233