2016-11-22 2 views
0

J'ai actuellement quelques difficultés à surcharger les crochets dans une classe de vecteurs personnalisés.Surcharges entre crochets => aucun opérateur ne correspond à des opérandes

Ma classe ressemble fondamentalement ceci:

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

Et dans ce fonctions de classes, je peux appeler (* cela) [0] et tout fonctionne. Maintenant, la question que je vais avoir est avec une classe qui a un membre comme suit:

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

Le problème étant que mon compilateur renvoie une erreur à mon visage en disant

aucun opérateur « [] "correspond à ces opérandes

types d'opérandes sont: const JFFVector [U32]

typedef uint32_t U32.

donc une chose que je remarque est que si je fais m_tItems un pointeur, alors je peux faire "(* m_tItems) [i] -> DoStuff()" et il fonctionne très bien. Mais je ne comprends pas pourquoi cela fonctionne avec une version sans pointeur. (En outre, j'ai essayé avec un simple int au lieu de u32, et, sans surprise, cela n'a pas fonctionné)

Est-ce que quelqu'un a une idée de ce que j'ai mal fait s'il vous plaît? Et, si ce n'est pas trivial, pourquoi est-ce faux?

(Désolé si cela a été déjà répondu, j'ai essayé la recherche d'un problème similaire, mais n'a rien trouvé qui ressemble à cette question)

Répondre

2

Il y a deux opérateurs d'indexation, vous pouvez surcharger - celui qui fonctionne sur un const JFFVector et retourne un T const&, et qui travaille sur un JFFVector et retourne un T&. Vous avez seulement mis en place la seconde.

Vous pouvez la mettre en œuvre de façon similaire à la version non-const comme ceci:

T const& operator[](u32 iIndex) const // <-- note the two `const`s 
{ 
    return m_pData[iIndex + miDataOffset]; 
} 

Notez que cette surcharge est pas spécifique à operator[], mais plutôt toutes les méthodes (qui peuvent être surchargées par const ou non const).

La raison pour laquelle vous avez besoin de la version const dans votre code est que DoSomething() est déclarée const, ainsi this est const TOtherClass* dans cette méthode, et par extension tous ses membres, notamment m_tItems ici, sont const dans la méthode, et ainsi que const des méthodes peuvent être appelées. Comme il n'y a pas de const version de operator[] définie pour m_tItems, le compilateur vous donne cette erreur.

+0

droit. Dayum. En fait, je suis tombé pour cette erreur. Merci mon pote! – Thex

0

Vous avez besoin version 2, un pour const et un sans const. Un pour le const JFFVector immuable et un pour mutable JFFVector.

Dans ce cas, DoSomething est une fonction const, elle veut appeler une fonction 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; 
} 
1

Lorsqu'en const, il faut rester const. Le compilateur n'a aucun moyen facile de savoir que ce qui se passe dans m_tItems[i] ne change pas m_tItems et ainsi enfreindre la promesse que void DoSomething() const ne changerait pas l'état de TOtherClass.

Solution: Mettre en œuvre une constoperator[]

const T& operator[](u32 iIndex) const 
{ 
    return m_pData[iIndex + miDataOffset]; 
}