我有struct
个const
个变量
struct HashData
{
const HashKey key;
const void* data;
HashData(const HashKey& key_, const void* data_) : key(key_), data(data_) {}
/* How to write this ?
HashData operator=(const HashData & data)
{
key = std::move(data.key);
return *this;
}
*/
};
和我使用它的另一个类。
class HashTable
{
std::vector< std::list<HashData> > hashTable; ///< Collisions resolution by chaining.
public:
void insertAtIndex(const std::size_t index, const HashData& data) {
hashTable[index].insert(std::begin(hashTable[index]), data);
}
};
类HashTable
编译但是另一个类
class OpenAddressHashTable
{
std::vector<HashData> hashTable;
public:
void insert(const HashData & data) throw() {
if (data.key == NULLKEY)
throw std::runtime_error("Do not use NullKey");
size_t iteration = 0;
do {
const size_t index = (*hashFunc)(data.key, iteration);
if (hashTable[index].key == NULLKEY) {
// space is free
// ** IMPORTANT **///// Line 131 is next line
hashTable[index] = data;
return ;
}
iteration++;
} while(iteration < hashTable.size());
throw std::runtime_error("No space left");
}
};
我收到此错误:
g++ -W -Wall -pedantic -std=c++11 hash.cpp
hash.cpp: In member function 'void OpenAddressHashTable::insert(const HashData&)':
hash.cpp:131:24: error: use of deleted function 'HashData& HashData::operator=(const HashData&)'
hash.cpp:26:8: note: 'HashData& HashData::operator=(const HashData&)' is implicitly deleted because the default definition would be ill-formed:
hash.cpp:26:8: error: non-static const member 'const HashKey HashData::key', can't use default assignment operator
std::list
我需要将数据放入向量中是什么意思?
我是否需要在hashTable
使用指针?
答案 0 :(得分:3)
编译器删除类HashData
的赋值运算符,因为它具有常量字段(键和数据)。这是有道理的,因为你不能为const成员分配东西,因此对象是const成员生活不应该被分配以太。
您的HashData类是不可变的。如果您希望类是这样,那么这可能没问题,但由于inmutability,无法执行类OpenAddressHashTable中的赋值。
关于你的&#34; const void * data&#34;字段:真的更像C ++就像在这里使用泛型。
你可以这样做:
template<typename T>
struct HashData
{
HashKey key; // delete the const if you really want to modify a instance of HashData
T data;
HashData(const HashKey& key_, T data_) : key(key_), data(data_) {}
};
T将是您映射值的类型。这可能会迫使您所有的值都具有相同的类型,这可能不是问题。
答案 1 :(得分:2)
你正在做作业:
hashTable[index] = data;
如果您拥有const
成员,则根本无法使用,因为您无法复制或迁移到const
。编译器错误非常明确:
[赋值运算符]被隐式删除,因为默认定义是错误的
您希望分配对key
和data
做什么?最简单的方法是删除const
并在用户界面上强制执行 - 这样他们就无法从你下面更改密钥。例如:
using InternalHashData = std::pair<HashKey, void*>;
using ExternalHashData = std::pair<const HashKey, void*>;
InternalHashData& something_to_be_returned = ..; // never expose this
return reinterpret_cast<ExternalHashData&>(something_to_be_returned); // this is OK
我能想到保持 const
的唯一方法就是改变你的表:
std::vector<HashData> hashTable;
到
std::vector<std::unique_ptr<HashData>> hashTable;
但是你要在每个插页上进行额外的分配只是为了保留const
- ness,这对我来说似乎不是一个很好的权衡,特别是对于一个单独的容器目的是表现。
答案 2 :(得分:1)
hashTable[index].insert(std::begin(hashTable[index]), data);
将在索引处保存的链接列表的前面插入新的HashData
对象。这意味着对复制构造函数的调用,默认情况下为HashData
定义。 (默认的复制构造函数复制构造其所有成员,const
成员是可复制的,因为您设置的是初始值,而不是覆盖现有的成员)
hashTable[index] = data;
将分配给现有的HashData
对象,但默认情况下会为HashData
删除分配。 (它的所有成员都是不可分配的,因为你已将它们全部声明为const
)
您可以做的是让HashData
的成员为非const
,但只返回 const引用和const迭代器到{{1}中的私有向量}}。这会将OpenAddressHashTable
个对象保持为HashData
,除非实际管理它们,这似乎是您的目标。