c++ - C++ no matching constructor initialization of []
问题描述
I have a function like so:
#include <stdio.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv/cxcore.h>
#include <math.h>
#define PI 3.14159265
#define GRADIENT_THRESHOLD 200.0
#define ANGLE_RANGE 20
using namespace cv;
using namespace std;
class Circle {
public:
int x;
int y;
int r;
Circle(int x, int y, int r) {
this->x = x;
this->y = y;
this->r = r;
}
double area() {
return PI * pow(r, 2);
}
};
Vector <Circle> collect_circles_from_houghSpace(Mat &houghSpaceCircle, double voting_threshold) {
int height = houghSpaceCircle.size[0];
int width = houghSpaceCircle.size[1];
int radius = houghSpaceCircle.size[2];
std::vector <Circle> circles;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
for (int r = 0; r < radius; r++) {
if (houghSpaceCircle.at<cv::Vec3i>(y, x)[r] > voting_threshold) {
circles.push_back(Circle(x, y, r));
}
}
}
}
return circles;
}
When I compile it, I get an error saying: In file included from sobel.cpp:2:
In file included from /usr/local/Cellar/opencv@2/2.4.13.7_5/include/opencv/cv.h:64:
In file included from /usr/local/Cellar/opencv@2/2.4.13.7_5/include/opencv2/core/core.hpp:4932:
/usr/local/Cellar/opencv@2/2.4.13.7_5/include/opencv2/core/operations.hpp:2415:23: error: no matching constructor for initialization of 'Circle []'
newData = new _Tp[newCapacity];
^
/usr/local/Cellar/opencv@2/2.4.13.7_5/include/opencv2/core/operations.hpp:2400:13: note: in instantiation of member function 'cv::Vector<Circle>::reserve' requested here
reserve(_size);
^
/usr/local/Cellar/opencv@2/2.4.13.7_5/include/opencv2/core/operations.hpp:2305:7: note: in instantiation of member function 'cv::Vector<Circle>::set' requested here
{ set(!vec.empty() ? (_Tp*)&vec[0] : 0, vec.size(), _copyData); }
^
sobel.cpp:166:12: note: in instantiation of member function 'cv::Vector<Circle>::Vector' requested here
return circles;
^
sobel.cpp:15:7: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided
class Circle {
^
sobel.cpp:21:5: note: candidate constructor not viable: requires 3 arguments, but 0 were provided
Circle(int x, int y, int r) {
^
1 error generated.
Could someone explain the error to me and how to fix it? As I see it, I have created a constructor that takes in 3 arguments. I'm not sure I understand why the error is saying I have provided 0 args.
解决方案
The essential part of your function is:
cv::Vector<Circle> foo() {
std::vector <Circle> circles;
return circles;
}
Here the type of circles
is not the return type. A type conversion should take place. cv::Vector<T>
has an implicit constructor
Vector(const std::vector<T>& vec, bool copyData = false)
that will be called to perform the conversion.
std::vector<T>
itself does not require T
to be default constructible, so the error happens inside cv::Vector<T>::Vector
. Its reserve()
member function, which is called during construction, has the following line:
newData = new T[newCapacity];
This line does require T
to be default constructible. That's why you get the error and that's why reserve()
is mentioned in the error log. To fix it, declare a defaulted default constructor:
class Circle {
public:
Circle() = default;
...
};
Also note, that data from circles
will not be copied into Vector
unless you set copyData
to true
. The return
statement should look like this:
return {circles, true};
or
return cv::Vector<Circle>(circles, true);
With
return circles;
cv::Vector
will store a pointer to &circles[0]
, that will become invalid after the local object circles
is destroyed when the function returns.
A comment about std::move
. You could try to do
return Vector<Circle>(std::move(circles), true);
This will not move anything. The shallow reason: the first constructor parameter has type const std::vector<T>& vec
, you can't move from it, it's const
. And the deep reason: to move from std::vector
means to copy (or swap) an internal pointer to heap-allocated buffer. Implementation of std::vector
is not specified, so there is no way to reuse its buffer in user-defined types like cv::Vector
. cv::Vector
allocates its own storage and copies elements into it, and you can't do better if you want cv::Vector
to outlive std::vector
.
The move semantics could have been useful if cv::Vector
used std::vector
internally to store its data and the constructor looked like this
Vector(std::vector<T> vec) : internal_vec(std::move(vec)) { }
To avoid unnecessary copies, you might want to use cv::Vector<Circle> circles;
from the very beginning.
推荐阅读
- validation - Azure Active Directory B2C - 向(默认)注册用户流添加验证
- ios - 转换为 JSON
- angular - 未定义属性 在所有警报点填充属性
- mysql - 如何根据 MySQL 中的任务开始日期和结束日期计算每个季度的值总和?
- python-3.x - 表单内的树视图中的值未出现 Odoo 11
- javascript - 为什么不执行if语句
- flutter - 使用 json 文件为颤振提供 appbar 标志。导航时面临加载问题
- django - 有没有办法更改 Pandas 中附加的数据框的 ID?
- flutter - 如何使用getx statemanagment在flutter中更新选定的单选按钮
- reactjs - 函数调用后如何渲染反应组件?