簡體   English   中英

處理映射鍵中指向值的常量

[英]Handling constness of pointed values in map keys

我有以下代碼:

#include <map>
using namespace std;
struct A {};

map</*const*/ A *, int> data;

int get_attached_value(const A *p) {
    return data.at(p);
}
void reset_all() {
    for (const auto &p : data) *p.first = A();
}

我的問題是,當我在data類型中注釋和取消注釋const時,此代碼在類型錯誤上失敗。 有沒有什么辦法可以解決這個問題而不使用const_cast並且不會丟失get_attached_valueconst

問題似乎是在pointee類型中 ,它在兩個指針聲明中都必須相同(map key type和get_attached_value的參數)。

OP的代碼使用const A* ,它是指向類Aconst實例的指針(另一種拼寫是A const * )。 將此const保留在map聲明和get_attached_value '參數中幾乎可以正常工作,但reset_all不允許您為*p.first分配新值,因為結果類型是A const& (無法分配)。

刪除兩個consts也是有效的,但是OP希望在get_attached_value保留一個const。

OP的要求的一個解決方案,保持盡可能多的consts,似乎是將指針類型更改為指向A的非const實例的const指針 這將使reset_all保持工作,同時允許在map聲明和get_attached_value的參數中使用const指針:

#include <map>
using namespace std;
struct A {};

map<A * const, int> data;

int get_attached_value(A * const p) {
    return data.at(p);
}
void reset_all() {
    for (const auto &p : data)
        *p.first = A();
}

另一個可能的解決方案,map的鍵為非const但get_attached_value的參數const,可以使用std::lower_bound和自定義比較器來替換data.at()調用:

#include <map>
#include <algorithm>

using namespace std;
struct A {};

map<A*, int> data;

int get_attached_value(A const * const p) {
    auto it = std::lower_bound(data.begin(), data.end(), p,
        [] (const std::pair<A* const, int>& a, A const* const b) {
            return a.first < b;
        }
    );
    return it->second;
}
void reset_all() {
    for (const auto &p : data)
        *p.first = A();
}

但是,此解決方案的效率遠低於使用map的本機搜索功能的解決方案 - 當輸入迭代器不是隨機訪問時, std::lower_bound 使用線性搜索

總而言之,C ++ 11或更低版本中最有效的解決方案可能使用const指針作為映射的鍵,並使用reset_all函數中的const_cast

關於const表示法和指針的更多閱讀可以在這里找到。

暫無
暫無

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

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