[英]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 的索引返回int
或std::string
。
不可能。 function 有一種返回類型。 auto
也不是魔術。 如果您不能編寫實際類型,那么編譯器也不能。
B) 你想返回mapped_type
的 mapped_type。
您可以從 function 返回std::variant<int, std::string>
。
您的get
不能比std::variant::get
做得“更好”。 使用std::variant::get
您需要在編譯時指定要檢索的類型。 如果您想獲得int
或std::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.