我目前在自定义矢量类中重载方括号时遇到了一些麻烦。
我的班级基本上是这样的:
typedef uint32_t u32; // This is not actually here, but so you get the idea. Also, it is included in the problematic call's file
template<class T>
class JFFVector
{
public:
//Init and stuff
T& operator[](u32 iIndex)
{
return m_pData[iIndex + miDataOffset];
}
private:
T* m_pData;
u32 m_iDataOffset;
}
在这个类函数中,我可以调用(* this)[0]并且一切正常。 现在我遇到的问题是一个拥有如下成员的类:
class TOtherClass
{
public:
// Stuff
void DoSomething() const
{
for (u32 i; i < m_tItems.size(); ++i)
m_tItems[i]->DoStuff(); // Which is a const function
}
private:
JFFVector<const JFFItem*> m_tItems;
}
问题在于我的编译器在我的脸上抛出错误
没有操作员&#34; []&#34;匹配这些操作数
操作数类型是:const JFFVector [u32]
typedef uint32_t u32。
所以我注意到的一件事是,如果我将m_tItems作为指针,那么我可以做&#34;(* m_tItems)[i] - &gt; DoStuff()&#34;它工作正常。但是我不明白为什么这个有效,而它没有非指针版本。 (另外,我尝试使用简单的int而不是u32,毫不奇怪,它没有工作)
有人知道我做错了吗?而且,如果不是微不足道的,为什么会出错?
(对不起,如果已经回答了这个问题,我尝试搜索类似的问题,但发现没有看起来像这个问题)
答案 0 :(得分:2)
您可以重载两个索引操作符 - 一个适用于const JFFVector
并返回T const&
,另一个适用于JFFVector
并返回T&
。你只实现了第二个。
您可以像非const版本一样实现它:
T const& operator[](u32 iIndex) const // <-- note the two `const`s
{
return m_pData[iIndex + miDataOffset];
}
请注意,此重载并非特定于operator[]
,而是所有方法(可以由const
或非const
重载)。
您需要在代码中使用const版本的原因是DoSomething()
被声明为const
,因此this
在该方法中为const TOtherClass*
,并且通过扩展名为其所有成员,特别是m_tItems
,方法中const
,因此只能调用const
个方法。由于const
没有为operator[]
定义m_tItems
版本,编译器会为您提供该错误。
答案 1 :(得分:1)
在const
时,必须留下const
。编译器没有简单的方法可以知道m_tItems[i]
中发生的事情不会改变m_tItems
,从而违反了void DoSomething() const
不会改变TOtherClass
状态的承诺。
解决方案:实施const
operator[]
const T& operator[](u32 iIndex) const
{
return m_pData[iIndex + miDataOffset];
}
答案 2 :(得分:0)
您需要2个版本,一个用于const
,另一个用于const
。一个用于不可变const JFFVector
,一个用于可变JFFVector
。
在这种情况下,DoSomething
是一个const函数,它想调用一个const函数。
template<class T>
class JFFVector
{
public:
//Init and stuff
T& operator[](u32 iIndex)
{
return m_pData[iIndex + miDataOffset];
}
const T& operator[](u32 iIndex) const
{
return m_pData[iIndex + miDataOffset];
}
private:
T* m_pData;
u32 m_iDataOffset;
}