我正在处理一个包含私有嵌套节点类的链表类。我想通过使用重载加法运算符在我的列表中前进n个节点但是clang给我错误“重载'运算符+'必须是一元或二元运算符(有3个参数)”。当你将它声明为友元函数时,我认为隐含的this参数消失了。
首先是我的头文件
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;
}
答案 0 :(得分:1)
从根本上说,你要做的事情的问题在于它是指针上的操作符。这是problematic。尽可能简化代码,以下内容不构建:
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;
}
};
...
};
答案 1 :(得分:1)
如前所述,在指针上重载操作符是有问题的,同样,最简单的方法是使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;
}
有关更高级的示例,请参阅here。