我已经将节点类和序列类实现为模板类。他们的测试程序运行良好,但是当我尝试使用我提供的测试程序时,我收到了这个错误。
类型' const double'的绑定值引用类型' double'滴' const'限定符
错误指向我代码中的几个不同位置:
在main.cpp中,它指向下面的if语句:
if (*itr != i)
{
// Our iterators have not ended with us on the correct value.
cout << "\nIncorrect value found.\n";
cout << "Expected: " << i << ". Found: " << *itr << "." << endl;
return 0;
}
在node2.h中,它指向下面的return语句:
Item& operator *( )
{ return current->data( ); }
我已经包含了我的node2.h和node2.cxx。我不能100%确定这个错误意味着什么以及它如何适用于我的程序。非常感谢任何帮助。
node2.h:
#ifndef COEN_79_NODE_H
#define COEN_79_NODE_H
#include <cstdlib> // Provides size_t and NULL
#include <iterator>
#include <cassert>
namespace coen79_lab8
{
template <class Item>
class node
{
public:
// TYPEDEF
typedef Item value_type;
// CONSTRUCTOR
node(const Item& init_data = Item( ), node* init_link = NULL)
{
data_field = init_data;
link_field = init_link;
}
// Member functions to set the data and link fields:
void set_data(const Item& new_data) { data_field = new_data; }
void set_link(node* new_link) { link_field = new_link; }
// Constant member function to retrieve the current data:
const Item& data( ) const { return data_field; }
// Two slightly different member functions to retreive
// the current link:
const node* link( ) const { return link_field; }
node* link( ) { return link_field; }
private:
Item data_field;
node* link_field;
};
// FUNCTIONS for the linked list toolkit
template <class Item>
size_t list_length(const node<Item>* head_ptr);
template <class Item>
void list_head_insert(node<Item>*& head_ptr, const Item& entry);
template <class Item>
void list_insert(node<Item>* previous_ptr, const Item& entry);
template <class NodePtr, class Item>
NodePtr list_search(NodePtr head_ptr, const Item& target);
template <class NodePtr, class SizeType>
NodePtr list_locate(NodePtr head_ptr, SizeType position);
template <class Item>
void list_head_remove(node<Item>*& head_ptr);
template <class Item>
void list_remove(node<Item>* previous_ptr);
template <class Item>
void list_clear(node<Item>*& head_ptr);
template <class Item>
void list_copy(const node<Item>* source_ptr, node<Item>*& head_ptr, node<Item>*& tail_ptr);
// YOU NEED TO IMPLEMENT THE FOLLOWING FUNCTIONS
template <class NodePtr, class Item>
void list_piece(NodePtr start_ptr, NodePtr end_ptr, node<Item>*& head_ptr, node<Item>*& tail_ptr);
template <class Item>
size_t list_occurrences(node<Item>* head_ptr, const Item& target);
template <class Item>
void list_insert_at(node<Item>*& head_ptr, const Item& entry, size_t position);
template <class Item>
Item list_remove_at(node<Item>*& head_ptr, size_t position);
template <class NodePtr, class Item>
NodePtr list_copy_segment(node<Item>* head_ptr, size_t start, size_t finish);
// FORWARD ITERATORS to step through the nodes of a linked list
// A node_iterator of can change the underlying linked list through the
// * operator, so it may not be used with a const node. The
// node_const_iterator cannot change the underlying linked list
// through the * operator, so it may be used with a const node.
// WARNING:
// This classes use std::iterator as its base class;
// Older compilers that do not support the std::iterator class can
// delete everything after the word iterator in the second line:
//You need to change these to template classes and implement the functions for these classes
template <class Item>
class node_iterator
: public std::iterator<std::forward_iterator_tag, Item>
{
public:
node_iterator(node<Item>* initial = NULL)
{ current = initial; }
Item& operator *( )
{ return current->data( ); }
node_iterator& operator ++( )
{
current = current->link( );
return *this;
}
node_iterator operator ++(int)
{
node_iterator original(current);
current = current->link( );
return original;
}
bool operator ==(const node_iterator other) const
{ return current == other.current; }
bool operator !=(const node_iterator other) const
{ return current != other.current; }
private:
node<Item>* current;
};
template <class Item>
class const_node_iterator
: public std::iterator<std::forward_iterator_tag, const Item>
{
public:
const_node_iterator(const node<Item>* initial = NULL)
{ current = initial; }
const Item& operator *( ) const
{ return current->data( ); }
const_node_iterator& operator ++( )
{
current = current->link( );
return *this;
}
const_node_iterator operator ++(int)
{
const_node_iterator original(current);
current = current->link( );
return original;
}
bool operator ==(const const_node_iterator other) const
{ return current == other.current; }
bool operator !=(const const_node_iterator other) const
{ return current != other.current; }
private:
const node<Item>* current;
};
}
#include "node2.cxx"
#endif
node2.cxx:
// FILE: node.cxx
// IMPLEMENTS: The functions of the node class and the
// linked list toolkit (see node2.h for documentation).
// INVARIANT for the node class:
// The data of a node is stored in data_field
// and the link to the next node is stored in link_field.
#include <cassert> // Provides assert
#include <cstdlib> // Provides NULL and size_t
namespace coen79_lab8
{
template <class Item>
size_t list_length(const node<Item>* head_ptr)
// Library facilities used: cstdlib
{
const node <Item> *cursor;
size_t answer;
answer = 0;
for (cursor = head_ptr; cursor != NULL; cursor = cursor->link( ))
++answer;
return answer;
}
template <class Item>
void list_head_insert(node<Item>*& head_ptr, const Item& entry)
{
head_ptr = new node<Item>(entry, head_ptr);
}
template <class Item>
void list_insert(node<Item>* previous_ptr, const Item& entry)
{
node<Item> *insert_ptr;
insert_ptr = new node<Item>(entry, previous_ptr->link( ));
previous_ptr->set_link(insert_ptr);
}
template <class NodePtr, class Item>
NodePtr list_search(NodePtr head_ptr, const Item& target)
// Library facilities used: cstdlib
{
NodePtr cursor;
for (cursor = head_ptr; cursor != NULL; cursor = cursor->link( ))
if (target == cursor->data( ))
return cursor;
return NULL;
}
template <class NodePtr, class SizeType>
NodePtr list_locate(NodePtr head_ptr, SizeType position)
// Library facilities used: cassert, cstdlib
{
NodePtr cursor;
SizeType i;
assert(0 < position);
cursor = head_ptr;
for (i = 1; (i < position) && (cursor != NULL); ++i)
cursor = cursor->link( );
return cursor;
}
template <class Item>
void list_head_remove(node<Item>*& head_ptr)
{
node<Item> *remove_ptr;
remove_ptr = head_ptr;
head_ptr = head_ptr->link( );
delete remove_ptr;
}
template <class Item>
void list_remove(node<Item>* previous_ptr)
{
node<Item> *remove_ptr;
remove_ptr = previous_ptr->link( );
previous_ptr->set_link(remove_ptr->link( ));
delete remove_ptr;
}
template <class Item>
void list_clear(node<Item>*& head_ptr)
// Library facilities used: cstdlib
{
while (head_ptr != NULL)
list_head_remove(head_ptr);
}
template <class Item>
void list_copy(const node<Item>* source_ptr, node<Item>*& head_ptr, node<Item>*& tail_ptr)
// Library facilities used: cstdlib
{
head_ptr = NULL;
tail_ptr = NULL;
// Handle the case of the empty list
if (source_ptr == NULL)
return;
// Make the head node for the newly created list, and put data in it
list_head_insert(head_ptr, source_ptr->data( ));
tail_ptr = head_ptr;
// Copy rest of the nodes one at a time, adding at the tail of new list
source_ptr = source_ptr->link( );
while (source_ptr != NULL)
{
list_insert(tail_ptr, source_ptr->data( ));
tail_ptr = tail_ptr->link( );
source_ptr = source_ptr->link( );
}
}
template <class NodePtr, class Item>
void list_piece(const NodePtr start_ptr, const NodePtr end_ptr, node<Item>*& head_ptr, node<Item>*& tail_ptr)
{
head_ptr = NULL;
tail_ptr = NULL;
// Handle the case of the empty list.
if (start_ptr == NULL)
{
return;
}
// Make the head node for the newly created list, and put data in it.
list_head_insert(head_ptr, start_ptr->data( ));
tail_ptr = head_ptr;
// Copy the rest of the nodes one at a time, adding at the tail of new list.
start_ptr = start_ptr->link( );
while (start_ptr != end_ptr)
{
list_insert(tail_ptr, start_ptr->data( ));
tail_ptr = tail_ptr->link( );
start_ptr = start_ptr->link( );
}
return;
}
template <class Item>
size_t list_occurrences(node<Item>* head_ptr, const Item& target)
{
size_t answer = 0;
for (head_ptr = list_search(head_ptr, target);
head_ptr != NULL;
head_ptr = list_search(head_ptr->link(), target))
answer++;
return answer;
}
template <class Item>
void list_insert_at(node<Item>*& head_ptr, const Item& entry, size_t position)
{
assert(position > 0);
node<Item> *precursor;
if (position == 1)
list_head_insert(head_ptr, entry);
else
{
precursor = list_locate(head_ptr, position-1);
assert(precursor != NULL);
list_insert(precursor, entry);
}
}
template <class Item>
Item list_remove_at(node<Item>*& head_ptr, size_t position)
{
assert(position > 0);
node<Item> *precursor;
Item answer;
if (position == 1)
{
assert(head_ptr != NULL);
answer = head_ptr->data();
list_head_remove(head_ptr);
}
else
{
precursor = list_locate(head_ptr, position-1);
assert(precursor != NULL);
assert(precursor->link() != NULL);
answer = precursor->link()->data();
list_remove(precursor);
}
return answer;
}
template <class NodePtr, class Item>
NodePtr list_copy_segment(node<Item>* head_ptr, size_t start, size_t finish)
{
node<Item> *start_ptr;
node<Item> *finish_ptr;
node<Item> *new_head;
node<Item> *new_tail;
assert((1 <= start) && (start <= finish) && (finish <= list_length(head_ptr)));
++finish;
start_ptr = list_locate(head_ptr, start);
assert(start_ptr != NULL);
finish_ptr = list_locate(start_ptr, finish-start+1);
list_piece(start_ptr, finish_ptr, new_head, new_tail);
return new_head;
}
}
答案 0 :(得分:1)
关键是这一行:
collections.defaultdict
在此声明data()方法返回对Item的const引用。由于您要返回引用,因此您不会复制该项,而是可以访问变量data_field。通常,如果您可以访问此数据,则可以对其进行修改。但是,您将引用声明为const引用,这意味着您禁止对其进行修改。
到目前为止这很好,但是你有了这个:
from collections import defaultdict
d = {k : type(v) for k, v in builtins.__dict__.items()}
d2 = defaultdict(list)
for k, v in d.items():
d2[v].append(k)
这将返回一个普通引用,而不是一个const引用,这意味着您说它可以被修改。但是current-&gt; data()返回一个const&amp;,所以这是“删除const限定符”,你违反了你声明data()返回const&amp;时所做的承诺。
有几种可能的解决方案:
让data()返回引用而不是const&amp; (只需删除const)
声明operator *()返回一个const Item&amp;而不是项目&amp;
更改
const Item& data( ) const { return data_field; }
到
Item& operator *( )
{ return current->data( ); }
这将告诉编译器您是故意丢弃const限定符,而不是抱怨