2014-12-31 63 views
1

我有一個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使用指針?

回答

2

你正在做的一個作業:

hashTable[index] = data; 

我們根本沒有辦法爲,如果你有const成員,因爲你不能複製或移動到const工作。編譯器錯誤是很明確的:

[賦值運算符]被隱式刪除,因爲默認定義將形成不良的

你會期望分配做keydata?最簡單的事情將是下降的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,這似乎不是一個很好的權衡,我在所有,特別是FO r唯一目的是表現的容器。

3

編譯器刪除HashData類的賦值運算符,因爲它具有常量字段(鍵和數據)。這是有道理的,因爲你不能給const成員分配一些東西,因此對象是const成員是活着的,不應該被賦予ether。 您的HashData類是不可變的。如果你希望這個類是這樣的,這可能是好的,但是你的類OpenAddressHashTable中的賦值不能被執行,因爲它的可交換性。

關於你的「const void * data」字段:真的更多的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將是你的映射值的類型。這種情況會迫使你所有的價值觀都是相同的,這可能不是問題。

+0

我的主要問題是std :: list如何與我的HashData類一起工作?它如何存儲這個類的一個實例?它從不使用=運算符嗎? –

+0

@AshishNegi:爲什麼呢? – Griwes

+0

所以,如果我從該點刪除節點,並在該索引插入一個新的,應該工作..但ot wpuld是O(N)..但理想情況下,因爲我只是改變這種記憶..我希望那裏會更好的方式..不犧牲常數。 –

1
hashTable[index].insert(std::begin(hashTable[index]), data); 

將在該索引處舉辦的鏈接列表的前面插入一個新的HashData對象。這意味着對複製構造函數的調用,默認情況下,該構造函數爲HashData。 (一個默認的拷貝構造函數拷貝構造其所有成員,並const成員副本construable因爲你設置的初始值,而不是覆蓋現有的)

hashTable[index] = data; 

將分配給現有的HashData對象,但分配將被刪除默認爲HashData。 (它的所有成員都是nonassignable因爲你已經聲明它們都作爲const

你可以做的反而是有HashData爲非const的成員,但只返回常量引用和const迭代器私人矢量在OpenAddressHashTable。這將使您的HashData對象保持爲const,除非它們是實際管理的,這似乎是您的目標。