运行以下代码时
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有点草率)
答案 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。