C++ 如何在Visual Studio C+中的运行时定义二维数组+;11?
我正在尝试使用Visual Studio 2015 vc14 x64编译器在Windows上编译。该项目最初是为GNU GCC开发的。我现在有以下问题:C++ 如何在Visual Studio C+中的运行时定义二维数组+;11?,c++,c++11,visual-c++,C++,C++11,Visual C++,我正在尝试使用Visual Studio 2015 vc14 x64编译器在Windows上编译。该项目最初是为GNU GCC开发的。我现在有以下问题: // Compute distances between them const size_t N = vDescriptors.size(); float aDistances[N][N]; for(size_t i=0;i<N;i++) { aDistances[i][i]=0; for(size_t j=i+1;j&
// Compute distances between them
const size_t N = vDescriptors.size();
float aDistances[N][N];
for(size_t i=0;i<N;i++) {
aDistances[i][i]=0;
for(size_t j=i+1;j<N;j++) {
int distij = ORBmatcher::DescriptorDistance(vDescriptors[i],vDescriptors[j]);
aDistances[i][j]=distij;
aDistances[j][i]=distij;
}
}
随后,二维数组定义也失败(浮动距离[N][N];
)
在Visual C++中解决此问题的最佳方法是什么
更新:以下是完整的功能代码:
void MapPoint::ComputeDistinctiveDescriptors() {
// Retrieve all observed descriptors
vector<cv::Mat> vDescriptors;
map<KeyFrame*,size_t> observations;
{
unique_lock<mutex> lock1(mMutexFeatures);
if(mbBad)
return;
observations=mObservations;
}
if(observations.empty())
return;
vDescriptors.reserve(observations.size());
for(map<KeyFrame*,size_t>::iterator mit=observations.begin(), mend=observations.end(); mit!=mend; mit++) {
KeyFrame* pKF = mit->first;
if(!pKF->isBad())
vDescriptors.push_back(pKF->mDescriptors.row(mit->second));
}
if(vDescriptors.empty())
return;
// Compute distances between them
const size_t N = vDescriptors.size();
float aDistances[N][N];
for(size_t i=0;i<N;i++) {
aDistances[i][i]=0;
for(size_t j=i+1;j<N;j++) {
int distij = ORBmatcher::DescriptorDistance(vDescriptors[i],vDescriptors[j]);
aDistances[i][j]=distij;
aDistances[j][i]=distij;
}
}
// Take the descriptor with least median distance to the rest
int BestMedian = INT_MAX;
int BestIdx = 0;
for(size_t i=0;i<N;i++) {
vector<int> vDists(aDistances[i], aDistances[i]+N);
sort(vDists.begin(),vDists.end());
int median = vDists[0.5*(N-1)];
if(median<BestMedian) {
BestMedian = median;
BestIdx = i;
}
}
{
unique_lock<mutex> lock(mMutexFeatures);
mDescriptor = vDescriptors[BestIdx].clone();
}
}
void映射点::ComputedDistinctiveDescriptors(){
//检索所有观察到的描述符
矢量描述器;
地图观测;
{
独特的锁1(mMutexFeatures);
如果(mbBad)
返回;
观察=移动观测;
}
if(observations.empty())
返回;
vDescriptors.reserve(observations.size());
对于(map::iterator mit=observations.begin(),mend=observations.end();mit!=mend;mit++){
关键帧*pKF=mit->first;
如果(!pKF->isBad())
vDescriptors.push_back(pKF->mDescriptors.row(mit->second));
}
if(vdDescriptors.empty())
返回;
//计算它们之间的距离
const size_t N=vDescriptors.size();
浮点数[N][N];
对于(大小i=0;i您的问题
您试图在堆栈上创建一个2D数组(这不是标准的C++
,即使它可能在某些编译器上工作)。为此,需要在编译时知道大小,而在可能不是constexpr的对象上调用size()
快速修复
一个开箱即用的快速修复方法是只分配堆上的内存(以后不要忘记删除数组)
删除可以在如下函数中完成
template <typename T>
void delete2DArray(T** ptr, size_t NumRows)
{
for (size_t i = 0; i < NumRows; i++)
{
delete[] ptr[i];
}
delete[] ptr;
}
注意:我不太确定我是否做对了——也许你需要找一个
列而不是行(太晚了,不能直接思考)。如果是这种情况,您还应该更改Array2D类的内存布局,即在基线1D向量中对元素进行不同的排序。您的问题在于
您试图在堆栈上创建一个2D数组(这不是标准的C++
,即使它可能在某些编译器上工作)。为此,需要在编译时知道大小,而在可能不是constexpr的对象上调用size()
快速修复
一个开箱即用的快速修复方法是只分配堆上的内存(以后不要忘记删除数组)
删除可以在如下函数中完成
template <typename T>
void delete2DArray(T** ptr, size_t NumRows)
{
for (size_t i = 0; i < NumRows; i++)
{
delete[] ptr[i];
}
delete[] ptr;
}
注意:我不太确定我是否做对了——也许你需要找一个
列而不是行(太晚了,无法直接思考)。如果是这种情况,您还应该更改Array2D类的内存布局,即在基线1D向量中对元素进行不同的排序。使用新浮点[N][N]初始化浮点**
怎么样
?我将把一个std::vector
包装在一个简单的类中,使vector
。您与[]]
符号有多紧密?@πάνταῥεῖ: 我已经在“const size\u t N=vDescriptors.size();”处得到错误,并且“new float[N][N]'也需要一个常量。因此这似乎不是一个选项。@user4581301:我没有绑定到[]
notation,因为数组只在函数中定义和使用,所以作用域非常容易管理。我在原始文章中添加了完整的函数代码。如果从错误列表选项卡切换到输出选项卡,则可以更好地描述问题。它在const size\u t N=vDescriptors.size()上说明错误<代码>是<代码> n>代码>如何被使用<代码>浮点AcTe[n] [n];< /C> >。在C++中,数组必须用在编译时已知的常数来调整大小。在VisualStudio中,Visual Studio更贴近C++标准,要求编译时常数。对于<代码>浮点**/C> >用<代码> >新浮点[n][n]< /代码>?我将在一个简单的类中封装<代码> STD::vector < /C> >,使<代码>向量> >如何绑定到<代码> [][]。
你是谁?@πνταῥεῖ: 我已经在“const size\u t N=vDescriptors.size();”处得到错误,并且“new float[N][N]'也需要一个常量。因此这似乎不是一个选项。@user4581301:我没有绑定到[]
notation,因为数组只在函数中定义和使用,所以作用域非常容易管理。我在原始文章中添加了完整的函数代码。如果从错误列表选项卡切换到输出选项卡,则可以更好地描述问题。它在const size\u t N=vDescriptors.size()上说明错误<代码>是<代码> n>代码>如何被使用<代码>浮点AcTe[n] [n];< /C> >。在C++中,数组必须用在编译时已知的常数来调整大小。在VisualStudio中,VisualStudio更贴近C++标准,要求编译时常数。@ P.I:奇怪,如果我使用快速修复方法,我得到另一个<代码>表达式,必须有一个常量值<代码> <代码>浮点**距离=新浮点[n] [n];< /COD>指向<代码> [n] [n]
。我从size\t N=vDescriptors.size();
中删除了const
。太好了,我根据您的帮助构建了这个项目!谢谢您!@salocinx听到这个消息太好了!@pi:奇怪,如果我使用快速修复方法,我会得到另一个表达式必须具有float**aDi的常量值
template <typename T>
void delete2DArray(T** ptr, size_t NumRows)
{
for (size_t i = 0; i < NumRows; i++)
{
delete[] ptr[i];
}
delete[] ptr;
}
template <typename T>
class Array2D
{
public:
Array2D(size_t numrows, size_t numcols) :
rows(numrows), columns(numcols), array2d(rows * columns)
{}
T& operator()(size_t row, size_t column)
{
return array2d[row * columns + column];
}
const T& operator()(size_t row, size_t column) const
{
return array2d[row * columns + column];
}
T* getRow(size_t row)
{
return &array2d[row * columns];
}
private:
size_t rows;
size_t columns;
std::vector<T> array2d;
};
// Compute distances between them
const size_t N = vDescriptors.size();
Array2D<float> aDistances(N,N);
for (size_t i = 0; i < N; i++) {
aDistances(i,i) = 0;
for (size_t j = i + 1; j < N; j++) {
int distij = ORBmatcher::DescriptorDistance(vDescriptors[i], vDescriptors[j]);
aDistances(i,j) = distij ;
aDistances(j,i) = distij ;
}
}
// Take the descriptor with least median distance to the rest
int BestMedian = INT_MAX;
int BestIdx = 0;
for(size_t i=0;i<N;i++) {
vector<int> vDists(aDistances.getRow()[i], aDistances.getRow()[i]+N);
sort(vDists.begin(),vDists.end());
int median = vDists[0.5*(N-1)];
if(median<BestMedian) {
BestMedian = median;
BestIdx = i;
}
}