[英]Addition operator overload for pointers to nested classes
我正在研究一個包含私有嵌套節點類的鏈表類。 我想通過使用重載加法運算符在列表中前移n個節點,但是clang給我一個錯誤“重載的'operator +'必須是一元或二進制運算符(具有3個參數)”。 我認為當您將其聲明為朋友函數時,隱式此參數便消失了。
首先是我的頭文件
template <class T>
class List
{
private:
class ListNode
{
public:
ListNode();
ListNode(const T& ndata);
friend ListNode* operator+(const ListNode* &node, int n);
ListNode* next;
ListNode* prev;
};
public:
friend ListNode* operator+(const ListNode* &node, int n);
我的實現如下:
template <class T>
typename List<T>::ListNode* List<T>::ListNode::operator+(const ListNode* &node, int n)
{
ListNode* current = node;
while (n--){
if (current->next != 0)
current = current->next;
}
return current;
}
從根本上講,您要執行的操作的問題在於,它使指針上的運算符過載。 這是有問題的 。 為此,將盡可能簡化代碼,但不會建立以下代碼:
class foo{};
foo *operator+(foo *, int) {
return nullptr;
}
int main() {}
嘗試給出:
$ g++ gl.cpp
gl.cpp:5:26: error: ‘foo* operator+(foo*, int)’ must have an argument of class or enumerated type
foo *operator+(foo *, int) {
如果您確實要使用operator+
,那么最簡單的方法可能是使用成員運算符形式:
template<class T>
class List {
class ListNode { ...
public:
ListNode &operator+(int n) {
ListNode *current = this;
while (n--)
if (current->next != 0)
current = current->next;
return *current;
}
};
...
};
但是,這有點讓人產生誤解,因為您實際上沒有在節點上添加整數,而是在獲取下一個節點。 next
方法可能更清晰:
template<class T>
class List {
class ListNode { ...
public:
ListNode *next(int n) {
ListNode *current = this;
while (n--)
if (current->next != 0)
current = current->next;
return current;
}
};
...
};
如前所述,在指針上重載運算符是有問題的,同樣,最簡單的方法是使operator+
成為成員函數。 但是,有一種方法可以獲取您想要的行為...
訣竅是將指針包裝在行為類似於指針的對象中(通常稱為iterator )。
一個工作示例來演示:
class List {
struct Node {
Node* next; int data;
};
Node* m_head{0};
public:
// the fake pointer type.
struct Iter {
Iter(Node* initial = 0)
: m_base(initial) {}
Node* operator->()
{ return m_base; }
bool operator!=(const Iter& other) const
{ return m_base != other.m_base; }
private:
Node* m_base;
};
// get head as fake pointer.
Iter head()
{ return m_head; }
void push_front(const int&);
};
void List::push_front(const int& x)
{
Node* n = new Node;
n->data = x;
n->next = m_head; m_head = n;
}
// non-member operator.
List::Iter operator+(List::Iter i, int count)
{
for ( ; count > 0 && i != 0; count-- )
i = i->next;
return i;
}
int main(int argc, char* argv[])
{
List list;
for ( int i = 0; i < 10; i++ )
list.push_front(i);
for ( auto i = list.head(); i != 0; i = i+1 )
std::cout << i->data << ' ';
std::cout << std::endl;
return 0;
}
有關更高級的示例,請參見此處 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.