C++ 如何在Visual Studio C+中的运行时定义二维数组+;11?

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&

我正在尝试使用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<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;
    }
}