簡體   English   中英

const成員和運算符=

[英]const members and operator=

我有一個帶有一些const變量的struct

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使用指針嗎?

編譯器刪除類HashData的賦值運算符,因為它具有常量字段(鍵和數據)。 這是有道理的,因為您不能為const成員分配任何東西,因此不應為const成員所居住的對象分配以太幣。 您的HashData類是不可變的。 如果您希望類是這樣,可以這樣做,但是由於不可變性,因此無法執行類OpenAddressHashTable中的分配。

此外,還涉及“ const void *數據”字段:實際上,更多的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將是您映射值的類型。 這樣做會迫使您所有值都具有相同的類型,這可能不是問題。

您正在執行作業:

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,這對我來說似乎並不是一個很好的權衡,尤其是對於僅以性能為目的的容器而言。

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

將在索引所在的鏈表的前面插入一個新的HashData對象。 這意味着調用復制構造函數,該構造函數默認情況下為HashData定義。 (默認的復制構造函數copy構造其所有成員,並且const成員是可復制復制的,因為您設置的是初始值,而不是覆蓋現有的成員)

hashTable[index] = data;

將分配給現有的HashData對象,但是默認情況下, HashData分配被刪除。 (所有成員都是不可分配的,因為您已將它們全部聲明為const

相反,您可以做的是將HashData的成員設為非const ,但僅將const引用和const迭代器返回給OpenAddressHashTable的私有向量。 這將使HashData對象在除實際管理位置之外的所有地方都保持為const ,這似乎是您的目標。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM