Introduction: CSDN blog expert, focusing on Android/Linux System, share multi-mic voice solutions, audio and video, codec and other technologies, and grow with everyone!
Quality Column:Audio Engineer Advanced Series[Original information is being updated continuously… ]
Life motto: There are never shortcuts in life, only actions It is the only cure for fear and laziness.
For more original works, welcome to follow: Android System Siege Lion
1. Preface
The purpose of this article: Understand the usage of std::get in C++.
1. In C++, std::holds_alternative
is a template function used to check whether the given std::variant
object contains a value of the specified type. It returns a bool
value indicating whether the given type exists in std::variant
.
2. In C++, std::get
is used to obtain from types such as std::tuple
and std::variant
Function template for values. It accepts an index as a parameter and returns the value at the corresponding position.
3. In C++, std::variant
is a general polymorphic type introduced by the C++17 standard. It can store different types in a single variable. The purpose of std::variant
is to provide a type-safe way to handle multiple possible types.
std::variant
can store one of a set of predefined types, called an “optional type list”. When creating a std::variant
object, you need to specify a list of optional types. This way, you can store any of these types in the std::variant
object.
When using std::variant
, you can use std::get
to get the value stored in std::variant
, or use std::visit
to perform polymorphic processing on the value in std::variant
. In addition, you can also use std::holds_alternative
to check whether a specific type is stored in std::variant
.
2. Application examples
<1>.v1.0: std::variant application example
#include <variant> #include <iostream> #include <string> int main() {<!-- --> std::variant<int, std::string> var; var = 42; // Store a value of type int std::cout << std::get<int>(var) << std::endl; // Output: 42 var = "Hello"; // Store a value of type std::string std::cout << std::get<std::string>(var) << std::endl; // Output: Hello return 0; }
<2>.v2.0: std::holds_alternative usage
#include <iostream> #include <variant> #include <string> int main() {<!-- --> std::variant<int, double, std::string> myVariant = "Hello"; // Use std::holds_alternative to check whether the specified type exists in the variant bool isInt = std::holds_alternative<int>(myVariant); bool isDouble = std::holds_alternative<double>(myVariant); bool isString = std::holds_alternative<std::string>(myVariant); std::cout << "isInt: " << isInt << std::endl; // Output: isInt: 0 std::cout << "isDouble: " << isDouble << std::endl; // Output: isDouble: 0 std::cout << "isString: " << isString << std::endl; // Output: isString: 1 return 0; }
<3>.v3.0: For std::tuple
, usage of std::get
.
#include <iostream> #include <tuple> int main() {<!-- --> std::tuple<int, std::string, double> myTuple(42, "Hello", 3.14); // Use std::get to get the value in the tuple int intValue = std::get<0>(myTuple); std::string stringValue = std::get<1>(myTuple); double doubleValue = std::get<2>(myTuple); std::cout << intValue << std::endl; // Output: 42 std::cout << stringValue << std::endl; // Output: "Hello" std::cout << doubleValue << std::endl; // Output: 3.14 return 0; }
<4>.v4.0: Usage of std::get
for std::variant
.
#include <iostream> #include <variant> #include <string> int main() {<!-- --> std::variant<int, std::string, double> myVariant = 42; // Use std::get to get the value stored in the variant int intValue = std::get<int>(myVariant); std::cout << intValue << std::endl; // Output: 42 // Trying to use std::get to get a mismatched type will throw a std::bad_variant_access exception. try {<!-- --> std::string stringValue = std::get<std::string>(myVariant); } catch(const std::bad_variant_access & amp; e) {<!-- --> std::cout << "Error: " << e.what() << std::endl; // Output: Error: std::bad_variant_access } return 0; }
<5>.v5.0: std::holds_alternative, std::variant instances
#include <iostream> #include <variant> #include <string> #include <utility> using namespace std; using Elem = std::variant<std::monostate, int32_t, int64_t, double, std::string, std::pair<int64_t, int64_t>>; int main() {<!-- --> Elem e1 = 42; Elem e2 = "Hello, world!"; Elem e3 = 3.14; Elem e4 = std::make_pair(10, 20); if (std::holds_alternative<int32_t>(e1)) {<!-- --> int32_t value = std::get<int32_t>(e1); cout << "e1 is an int32_t: " << value << endl; } if (std::holds_alternative<std::string>(e2)) {<!-- --> std::string value = std::get<std::string>(e2); cout << "e2 is a string: " << value << endl; } if (std::holds_alternative<double>(e3)) {<!-- --> double value = std::get<double>(e3); cout << "e3 is a double: " << value << endl; } if (std::holds_alternative<std::pair<int64_t, int64_t>>(e4)) {<!-- --> std::pair<int64_t, int64_t> value = std::get<std::pair<int64_t, int64_t>>(e4); cout << "e4 is a pair: (" << value.first << ", " << value.second << ")" << endl; } return 0; }
<6>.v6.0 comprehensive application examples
#include <iostream> #include <string> #include<typeinfo> #include <variant> #include <map> using namespace std; class Item {<!-- --> public: template<typename S, typename T> Item & amp;set(S key, T value) {<!-- --> printf("xxx---------->%s(), line = %d, key = %s, vlaue = %d\ ",__FUNCTION__,__LINE__,key,value); //The findOrAllocateProp function returns the Prop object and then calls the set() function. Finally, the key value is set to mName and the value is set to mElem. findOrAllocateProp(key).set(value); return *this; } Item & amp;setInt32(const char *key, int32_t value) {<!-- --> printf("xxx---------->%s(), line = %d, key = %s, vlaue = %d\ ",__FUNCTION__,__LINE__,key,value); return set(key, value); } class Prop {<!-- --> public: using Elem = std::variant<std::monostate, int32_t, int64_t, double, std::string, std::pair<int64_t, int64_t>>; //1.Set the key value to mName void setName(const char *name) {<!-- --> printf("xxx---------->%s(), line = %d, name = %s\ ",__FUNCTION__,__LINE__,name); mName = name; } //2. Pass valuec to mElem. template <typename T> void set(const T & amp; value) {<!-- --> printf("xxx---------->%s(), line = %d, value = %d\ ",__FUNCTION__,__LINE__,value); mElem = value; //Get the value in mElem. int32_t val = std::get<int32_t>(mElem); printf("xxx---------->%s(), line = %d,val = %d\ ",__FUNCTION__,__LINE__,val); } public: std::string mName; Elem mElem; }; //findOrAllocateProp function returns the Prop object and then calls the set() function Prop & amp;findOrAllocateProp(const char *key) {<!-- --> auto it = mProps.find(key);//The value corresponding to the starting key is empty. if (it != mProps.end()){<!-- -->//Do not take this branch. return it->second; } Prop &prop = mProps[key]; prop.setName(key); printf("xxx---------->%s(), line = %d, key = %s, nName = %s\ ",__FUNCTION__,__LINE__,key,prop.mName.c_str( )); return prop; } std::map<std::string, Prop> mProps; }; int main(){<!-- --> Item it; it.setInt32("Tom", 18); }
<7>.v7.0
#include <iostream> #include <string> #include<typeinfo> #include <variant> #include <map> using namespace std; class Item {<!-- --> public: template<typename S, typename T> Item & amp;set(S key, T value) {<!-- --> printf("xxx---------->%s(), line = %d, key = %s, vlaue = %d\ ",__FUNCTION__,__LINE__,key,value); //The findOrAllocateProp function returns the Prop object and then calls the set() function. Finally, the key value is set to mName and the value is set to mElem. findOrAllocateProp(key).set(value); //Or // Prop m_prop = findOrAllocateProp(key); // printf("xxx---------->%s(), line = %d, key = %s, value = %d\ ",__FUNCTION__,__LINE__,m_prop.mName.c_str( ),std::get<int32_t>(m_prop.mElem)); return *this; } Item & amp;setInt32(const char *key, int32_t value) {<!-- --> printf("xxx---------->%s(), line = %d, key = %s, vlaue = %d\ ",__FUNCTION__,__LINE__,key,value); return set(key, value); } //key: mName; value:mElem. class Prop {<!-- --> public: using Elem = std::variant<std::monostate, int32_t, int64_t, double, std::string, std::pair<int64_t, int64_t>>; //1.Set the key value to mName void setName(const char *name) {<!-- --> printf("xxx---------->%s(), line = %d, name = %s\ ",__FUNCTION__,__LINE__,name); mName = name; } //2. Pass valuec to mElem. template <typename T> void set(const T & amp; value) {<!-- --> mElem = value; //Get the value in mElem. int32_t val = std::get<int32_t>(mElem); printf("xxx---------->%s(), line = %d,val = %d\ ",__FUNCTION__,__LINE__,val); } public: std::string mName;//key Elem mElem;//value }; //findOrAllocateProp function returns the Prop object and then calls the set() function Prop & amp;findOrAllocateProp(const char *key) {<!-- --> auto it = mProps.find(key);//The value corresponding to the starting key is empty. if (it != mProps.end()){<!-- -->//Do not take this branch. return it->second; } Prop &prop = mProps[key]; prop.setName(key); return prop; } std::map<std::string, Prop> mProps; }; int main(){<!-- --> Item it; it.setInt32("Tom", 18); }