Reputation: 13
I'm trying to create a class for a hash table to contain unique pointers, but whenever I try to add a pointer to the table I get an error which points to a different file from a library I am using.
I've tried using .insert()
instead of .emplace()
. I've tried passing in a pair of the key and the pointer.
Both of these have resulted in a different error to the original
here is the Hash_Table class:
///<summary>
/// A struct for a hash table
///</summary>
template <typename T>
struct Hash_Table
{
public:
///<summary>
/// Add an item to the hash table & return the item key
///</summary>
int addItem(T newItem) {
// Make the item into a unique pointer
std::unique_ptr<T> itemPtr = std::make_unique<T>(newItem);
//std::pair<int, std::unique_ptr<T>> pair = std::make_pair(tailPointer, itemPtr);
while (!Table.emplace(tailPointer, itemPtr).second) {
tailPointer++;
//pair.first++;
}
tailPointer++;
return tailPointer--;
};
private:
///<summary>
/// The actual hash table
///</summary>
std::unordered_map<int, std::unique_ptr<T>> Table;
///<summary>
/// Points to the key of the last item added to the hash table
///</summary>
int tailPointer;
};
The issue happens in addItem()
function when I try to table.emplace()
.
Error in file xmemory for code as shown above:
C2661: 'std::pair::pair': no overloaded function takes 2 arguments
Error in file HashTable.h for when using table.insert()
:
C2664: 'std::_List_iterator>> std::_Hash>,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>::insert(std::_List_const_iterator>>,const std::pair>> &)': cannot convert argument 1 from 'int' to 'std::_List_const_iterator>>'
Error in file utility for when using table.insert
or table.emplace(std::make_pair(tailPointer, itemPtr))
:
C2440: '': cannot convert from 'initializer list' to '_MyPair'
Upvotes: 1
Views: 7489
Reputation: 5418
Multiple ways to fix your issue:
Solution 1:
int addItem(T newItem) {
// Make the item into a unique pointer
std::unique_ptr<T> itemPtr = std::make_unique<T>(newItem);
// Unique_ptr doesn't have assignment operator instead it has move-assignment.
// So it need to be moved only
std::pair<int, std::unique_ptr<T>> pair = std::make_pair(tailPointer++, std::move(itemPtr));
// For same above reason, it must be moved
Table.insert(std::move(pair));
return tailPointer;
};
Solution 2:
int addItem(T newItem) {
Table.insert(std::make_pair(tailPointer++, std::make_unique<T>(newItem)));
return tailPointer;
}
Solution 3:
int addItem(T newItem) {
Table[tailPointer++] = std::make_unique<T>(newItem);
return tailPointer;
}
Non of the above solutions will require C++ 17. All are from C++11. You should understand why you are getting the compilation error. With your existing code you are trying to assign or copy the unique_ptr which is not allowed. It can only be moved. This is what your compiler is trying to tell you.
Upvotes: 1
Reputation: 2933
Using this, will resolve the unique_ptr problems, in c++11
int addItem(T newItem) {
// Make the item into a unique pointer
while (!Table.emplace_hint(tailPointer, newItem).second) {
tailPointer++;
//pair.first++;
}
tailPointer++;
return tailPointer--;
};
Upvotes: 0
Reputation: 13
Thank you Jarod42, your fix did work.
The fix:
Table.emplace(tailPointer, itemPtr)
-> Table.try_emplace(tailPointer, std::move(itemPtr))
(but C++17). - Jarod42
Upvotes: 0