方括号重载=>没有运算符匹配操作数

时间:2016-11-22 23:32:32

标签: c++ templates operator-overloading brackets

我目前在自定义矢量类中重载方括号时遇到了一些麻烦。

我的班级基本上是这样的:

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,毫不奇怪,它没有工作)

有人知道我做错了吗?而且,如果不是微不足道的,为什么会出错?

(对不起,如果已经回答了这个问题,我尝试搜索类似的问题,但发现没有看起来像这个问题)

3 个答案:

答案 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;
}