std::variant 是 C++17 標準引入的一種 union,std::variant 可以在一個變數中存儲不同類型的數據,並保持類型安全,這是傳統的 union 所不能提供的。
主要特點#
類型安全#
使用 std::variant 可以保證任何時候都能確保訪問正確的類型值,如果訪問錯誤的類型會拋出 std::bad_variant_access 異常。
自動管理#
std::variant 和 std::any 可以管理內部數據的創建和銷毀,保證正確的資源管理。
訪問控制#
可以通過 std::get 訪問 std::variant 中的數據(需要確保類型正確)
可以和 visit 結合使用#
可以使用 std::visit 對存儲在 std::variant 中的數據進行操作。
示例#
#include <variant>
#include <iostream>
#include <string>
int main() {
std::variant<int, float, std::string> v;
v = 20;
std::cout << std::get<int>(v) << std::endl; // 輸出 20
v = 3.14f;
std::cout << std::get<float>(v) << std::endl; // 輸出 3.14
v = "Hello, world";
std::cout << std::get<std::string>(v) << std::endl; // 輸出 Hello, world
// 安全訪問
try {
std::cout << std::get<float>(v) << std::endl; // 嘗試獲取float,但當前是std::string,將拋出異常
} catch (const std::bad_variant_access& e) {
std::cout << e.what() << std::endl; // 輸出異常信息
}
// 使用 visit
std::visit([](auto&& arg) {
std::cout << arg << std::endl;
}, v); // 安全地打印當前存儲的值,這裡是 "Hello, world"
return 0;
}
在這個示例中,std::variant 被用來存儲一個 int,一個 float,和一個 std::string。可以看到如何安全地使用 std::get 來訪問 std::variant 中的數據,並且如何使用 std::visit 來應用函數或者訪問者到存儲的值上。
實際環境#
inline ResourceVariant ResourceManager::flipResource(ResourceVariant resource)
{
return std::visit([](auto&& res) -> ResourceVariant {
using T = std::decay_t<decltype(res)>;
if constexpr (std::is_same_v<T, IMAGE>) {
IMAGE flippedImg;
flipImage(&res, &flippedImg);
return flippedImg;
}
else if constexpr (std::is_same_v<T, Atlas>) {
Atlas flippedAtla;
flipAtlas(res, flippedAtla);
return flippedAtla;
}
}, resource);
}
這段代碼展示了如何使用 std::variant 和 std::visit 來處理不同類型的資源。這裡,ResourceManager::flipResource 方法接受一個名為 resource 的 ResourceVariant 類型的參數,並返回一個同樣類型的 ResourceVariant。這個 ResourceVariant 是一個 std::variant 類型,可以包含不同的資源類型(比如 IMAGE 或 Atlas)