шаблонная функция, принимающая cv :: Point_ <T>в качестве параметра, не будет компилироваться - PullRequest
0 голосов
/ 19 марта 2019

Я пытаюсь написать обобщенную функцию для сериализации в строку std::vector<cv::Point_<T>>, и я хочу, чтобы это работало как для cv::Point2i, так и cv::Point2f (оба являются typedefs cv::Point_<T> с определенным T).

Функция выглядит следующим образом:

template<typename T>
int SVIniFile::write(const std::string& section,
                     const std::string& key, 
                     std::vector<cv::Point_<T>>& points)
{
    std::ostringstream os;
    if (points.empty())
    {
        return SUCCESS;
    }
    for (size_t j = 0; j < points.size(); j++)
    {
        os << points[j].x << " " << points[j].y;
        if (j < points.size() - 1)
        {
            os << " ";
        }
    }

    write(section, key, os.str()); // do the writing of os.str() in the right `section` at `key`

    return SUCCESS; // function that writes a string into an ini file
}

Попытка скомпилировать это приводит к ошибке «Неузнаваемое объявление / определение шаблона». Исследуя ошибку (полный вывод компилятора приведен ниже), я обнаружил этот вопрос , который, тем не менее, не связан с моим делом, и этот вопрос , ответ на который я задал не понимаю.

Я очень новичок в программировании шаблонов, и я подозреваю, что ошибка вызвана тем фактом, что я использую в качестве параметра шаблона тип, который сам является параметром шаблона одного из параметров. Может ли кто-нибудь указать мне правильное направление и, возможно, немного рассказать о том, почему компилятор не может построить это?


Это то, что компилятор выдает как вывод ошибок в каждом файле, в который включен мой заголовок:

1> svinifile.h (640): ошибка C4430: отсутствует указатель типа - предполагается int. Примечание: C ++ не поддерживает default-int 1> svinifile.h (640): ошибка C2988: неузнаваемое объявление / определение шаблона 1> svinifile.h (640): ошибка C2143: синтаксическая ошибка: отсутствует ',' before '&'

строка 640 - та, что сразу после template<typename T> в определении функции, которое я показываю выше.


Просто чтобы быть точным, cv::Point_<T> i 2D тип точки OpenCV определен в types.hpp как:

namespace cv
{    
// ...
template<typename _Tp> class Point_
{
public:
    typedef _Tp value_type;

    //! default constructor
    Point_();
    Point_(_Tp _x, _Tp _y);
    Point_(const Point_& pt);
    Point_(Point_&& pt) CV_NOEXCEPT;
    Point_(const Size_<_Tp>& sz);
    Point_(const Vec<_Tp, 2>& v);

    Point_& operator = (const Point_& pt);
    Point_& operator = (Point_&& pt) CV_NOEXCEPT;
    //! conversion to another data type
    template<typename _Tp2> operator Point_<_Tp2>() const;

    //! conversion to the old-style C structures
    operator Vec<_Tp, 2>() const;

    //! dot product
    _Tp dot(const Point_& pt) const;
    //! dot product computed in double-precision arithmetics
    double ddot(const Point_& pt) const;
    //! cross-product
    double cross(const Point_& pt) const;
    //! checks whether the point is inside the specified rectangle
    bool inside(const Rect_<_Tp>& r) const;
    _Tp x; //!< x coordinate of the point
    _Tp y; //!< y coordinate of the point
};

typedef Point_<int> Point2i;
typedef Point_<int64> Point2l;
typedef Point_<float> Point2f;
typedef Point_<double> Point2d;
typedef Point2i Point;

}

1 Ответ

1 голос
/ 19 марта 2019

Так как в показанном коде нет ничего плохого, проблема должна быть в коде, который вы не показывали.Вероятно, это что-то очень простое, например, отсутствует или не соответствует # include.

Вам следует попытаться создать Минимальный, Полный и Проверяемый пример .Вероятно, вы найдете проблему при этом.

Например, это прекрасно компилируется на VS 2017:

#include <vector>

namespace cv {
    template<typename _Tp> class Point_ {};
    typedef Point_<int> Point2i;
}

class SVIniFile {
public:
    template<typename T>
    int write(
        const std::string& section,
        const std::string& key,
        std::vector<cv::Point_<T>>& points);
};

template<typename T>
int SVIniFile::write(
    const std::string& section,
    const std::string& key,
    std::vector<cv::Point_<T>>& points) {
    return 0;
}

int main() {
    SVIniFile svIniFile;
    std::vector<cv::Point2i> points;
    svIniFile.write("abc", "def", points);
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...