在c ++ 14中从“ const std :: vector <cv :: Mat> *”无效转换为“ std :: vector <cv :: Mat> *”

时间:2019-08-18 15:28:49

标签: c++ compiler-errors

运行以下代码时

RM_Analyzer.h:

struct FFeatureCalculationImages
{
    std::vector<cv::Mat>* cf_mat;
    std::vector<cv::Mat>* front_mat;
    std::vector<cv::Mat>* back_mat;
};

class RM_Analyzer
{
private: 
DLL_Mat<std::vector<cv::Mat> > sliding_window_frames;
void setImagesForExtendedFeatureCalculation(FFeatureCalculationImages &imgs) const;
}

RM_Analyzer.cpp

void RM_Analyzer::setImagesForExtendedFeatureCalculation(FFeatureCalculationImages &imgs) const
{
    imgs.cf_mat=sliding_window_frames[sliding_window_frames.size()-1-k];
    imgs.front_mat=sliding_window_frames.getFrontMat();
    imgs.back_mat=sliding_window_frames.getBackMat();
}

DLL_Mat.h

template<class T>
class DLLNode
{
public:
    DLLNode<T>* next;
    DLLNode<T>* previous;
    T im;
};


template<class T>
class DLL_Mat
{
private:
    unsigned count;
    DLLNode<T>* front;
    DLLNode<T>* back;

public:
    T* getFrontMat() const;
    T* getBackMat() const;
    unsigned size() const;
    T* operator[](const std::size_t idx);
    const T* operator[](const std::size_t idx) const;
};

template <class T>
inline unsigned DLL_Mat<T>::size() const
{
    return count;
}

template <class T>
T* DLL_Mat<T>::operator[](const std::size_t idx)
{
    if (idx==0)
        return getFrontMat();
    else if (idx==(count-1))
        return getBackMat();
    else if (idx>=size())
        return nullptr;
    else
    {
        std::size_t i=0;
        for (DLLNode<T> *iter=front;i<count;i++,iter=iter->next)
        {
            if (i==idx)
                return &(iter->im);
        }
    }

    return nullptr;
}

template <class T>
const T* DLL_Mat<T>::operator[](const std::size_t idx) const
{
    if (idx==0)
        return getFrontMat();
    else if (idx==(count-1))
        return getBackMat();
    else if (idx>=size())
        return nullptr;
    else
    {
        std::size_t i=0;
        for (DLLNode<T> *iter=front;i<count;i++,iter=iter->next)
        {
            if (i==idx)
                return &(iter->im);
        }
    }

    return nullptr;
}

为了方便起见,我包括了operator []源代码,尽管DLL_Mat.h和RM_Analyzer源代码中的函数声明可能足以找到问题的根源。

编译器似乎正在调用运算符[]的const版本, 进而导致转换错误。错误是(RM_Analyzer.cpp中的第3行):

error: invalid conversion from ‘const std::vector<cv::Mat>*’ to ‘std::vector<cv::Mat>*’ [-fpermissive]
     imgs.cf_mat=sliding_window_frames[sliding_window_frames.size()-1-k];

我的解释:
1)我似乎在某个地方犯了逻辑错误,因为函数setImagesForExtendedFeatureCalculation应该显然是const的,因为我没有在该方法中更改任何内部变量
2)编译器无法调用非常量运算符[],因为我将setImagesForExtendedFeatureCalculation方法声明为const,因此slide_window_frames也被视为const
3)由于参数(FFeatureCalculationImages)参数未声明为const(特别是cf_mat,front_mat,back_mat),因此无法调用运算符[]的const版本。

这似乎使我处于一个特殊的位置,这两个操作符[]方法都不适合,但是考虑到DLL_Mat.h中已有的两个方法,声明T* operator[] (const size_t idx) const;不可能重载。

关于如何规避无效转换错误而不丢弃const函数声明的任何建议? (因为我认为仅仅因为它对我来说方便而不将函数声明为const有点草率)

2 个答案:

答案 0 :(得分:1)

sliding_window_frames[sliding_window_frames.size()-1-k]中,编译器会调用operator[]的const版本。它返回指向const std::vector<cv::Mat>的指针。但是,然后您尝试将该指针分配给imgs.cf_mat,它是指向 non-const std::vector<cv::Mat>的指针。这违反了const正确性,因此编译器理应抱怨。

您有一个可以在该对象的const实例上调用的函数,试图分发指向该对象内部的可变指针。该函数要么不应该声明为const,要么应该派发const指针,或者它公开的内部应该标记为mutable

答案 1 :(得分:-1)

两个operator []方法都具有相同的签名(返回类型不是签名的一部分;编辑:由于此指针的恒定性,它们具有不同的签名),因此您无法选择要调用的方法。有两个相同的方法做同样的事情,但是一个返回const值是不正确的解决方案:您始终可以强制转换为const,但不能这样做,因此应删除返回const值的方法。

编辑: const对象的字段也具有const修饰符,因此将调用带有该指针的const的operator [](返回const指针)。

P。 S. Operator []在标头中使用const参数,但在定义中使用非const参数; size()应该返回std :: size_t。