簡體   English   中英

怎么可能返回map<int, variant> function 的價值?</int,>

[英]How could return map<int, variant>'s value by a function?

我想要一個 map 來保存不同類型的值,所以我有一個 map 之類的

std::map<int, std::variant<int, std::string>> m ={{1,1},{2,"asd"}};

現在我想設計一個 function 來通過它的鍵來獲取值

auto get(int key) {
    ...
    return value;
}

那就是說我想要的是什么樣的

get(1) -> 1
get(2) -> "asd"

那有可能嗎? 如果是這樣,確切的解決方案是什么?


添加

是的,至於設計的目的,我想保存從配置文件中讀取的配置數據。

閱讀后我需要進行一些類型更改或數據轉換。 例如在配置文件中

a=1
b=asd

並且讀完后想存為m["a"]=int(3) ---->指的是a=1需要在讀完它的實際數據1 m["b"]=std后加2 ::string("asdasd") ---->引用b=asd並且需要將其加倍

所以我覺得如果有一個接口 function 通過key獲取准確的值會更容易

兩種可能性:

A) 您想根據傳遞給 function 的索引返回intstd::string

不可能。 function 有一種返回類型。 auto也不是魔術。 如果您不能編寫實際類型,那么編譯器也不能。

B) 你想返回mapped_type的 mapped_type。

您可以從 function 返回std::variant<int, std::string>


您的get不能比std::variant::get做得“更好”。 使用std::variant::get您需要在編譯時指定要檢索的類型。 如果您想獲得intstd::string ,就沒有辦法解決這個問題。


可能有更好的方法來解決您的實際問題,您認為auto get(int key)是解決方案的方法。 一條評論(來自 Eljay)提到了std::visit 在那里你可以看到幾個如何處理變體的例子。

您不能使用此語法准確設計 function。 試想一下:

int key = 0;
if (rand() % 2) {
    key = 1;
} else {
    key = 2;
}

auto value = get(key);

這是謎語:

請告訴我get的返回類型和value的類型。 只能有一個答案,你只能用一種類型來回答,無論我問你這個問題多少次,它都不會改變。

如果你不能回答,那么編譯器也不能。

但是,這並不意味着您不能設計類似的東西來滿足您的需要。

您可以只返回變體。 這可能不是您要查找的內容,但值得注意,因為它不會更改get function 的任何輸入。

您也可以只發送預期的類型:

get<int>(key)

實現看起來像這樣:

template<typename T>
auto get(int key) -> T {
    return std::get<int>(m[key]);
}

如果您不知道預期的類型,那么您可以發送一個訪問者:

get(key, [](auto value) -> std::size_t {
    if constexpr (std::same_as<int, decltype(value)>) {
        // do stuff with value as an int since it's a int here
        return value + 1;
    } else {
        // do stuff with value as a string since it's a string here
        return value.size(); 
    }
});

實現看起來像這樣:

auto get(int key, auto visitor) -> decltype(auto) {
    return std::visit(visitor, m[key]);
}

如果我理解這些要求,您可以從get返回一個代理 object,它保留對variant的引用,並且根據您對代理 object 所做的操作,它可以適應。 例子:

#include <iostream>
#include <variant>
#include <map>
#include <string>

struct Foo {
    using variant = std::variant<int, std::string>;

    // the proxy object
    struct proxy {
        // assignment:
        template<class T>
        variant& operator=(T&& value) {
            *data = std::forward<T>(value);
            return *data;
        }

        // for static_cast to the wanted type
        explicit operator int& () { return std::get<int>(*data); }
        explicit operator std::string& () { return std::get<std::string>(*data); }

        variant* data;
    };

    proxy get(int key) {
        // return the proxy object
        return proxy{&m[key]};
    }

    std::map<int, std::variant<int, std::string>> m = {{1,1}, {2,"asd"}};
};

它可以這樣使用:

int main() {
    Foo f;
    
    // you need to know what it stores:
    std::cout << static_cast<int>(f.get(1)) << '\n';
    std::cout << static_cast<std::string>(f.get(2)) << '\n';

    // assigning is simple:
    f.get(1) = "hello world"; // was int, now std::string
    f.get(2) = 2;             // was std::string, now int

    std::cout << static_cast<std::string>(f.get(1)) << '\n';
    std::cout << static_cast<int>(f.get(2)) << '\n';
}

暫無
暫無

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

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