std::auto_ptr
.-std=c++1z
flag, which activates C ++ 17 features. #include <tuple> auto get() { return std::make_tuple("fred", 42); }
std::get
: auto t = get(); std::cout << std::get<0>(t) << std::endl;
std::tie
to bind tuple members to variables that you first want to declare: std::string name; int age; std::tie(name, age) = get();
std::get
, or you can first declare the variables: auto [name, age] = get(); std::cout << name << " is " << age << std::endl;
std::tie
. Here we get links to the members of the tuple and, when we change the value of one of them, the value of the whole tuple changes: auto t2 = std::make_tuple(10, 20); auto& [first, second] = t2; first += 1; std::cout << "value is now " << std::get<0>(t2) << std::endl;
t2
has changed from 10 to 11. struct Person { std::string name; uint32_t age; std::string city; }; Person p1{"bill", 60, "New York"}; auto [name, age, city] = p1; std::cout << name << "(" << age << ") lives in " << city << std::endl;
std::array<int32_t, 6> arr{10, 11, 12, 13, 14, 15}; auto [i, j, k, l, _dummy1, _dummy2] = arr;
std::tie
- you have to bind all the elements. Therefore, it is impossible, for example, to extract only the first four elements from an array. If you want to partially extract the structure or array, simply substitute stub variables for those members that you do not need, as shown in the example with the array.Location
member in the Person structure: struct Location { std::string city; std::string country; }; struct Person { std::string name; uint32_t age; Location loc; };
Person
and Location
by using nested initialization: Person2 p2{"mike", 50, {"Newcastle", "UK"}};
auto [n, a, [c1, c2]] = p2; //
std::byte
- it represents a single byte. For the representation of bytes, developers traditionally used char
(signed or unsigned), but now there is a type that can be not only a character or an integer; however, bytes can be converted to integer and back. The std::byte
designed to interact with the data store and does not support arithmetic operations, although it supports bitwise operations.'void'
).std::get
, like this: std::variant<uint32_t, std::string> age; age = 51; auto a = std::get<uint32_t>(age);
try { std::cout << std::get<std::string>(age) << std::endl; } catch (std::bad_variant_access &ex) { std::cout << "Doesn't contain a string" << std::endl; }
std::variant
, but not the usual union? Basically, because unions are present in the language primarily for compatibility with C and do not work with objects that are not related to POD-types. This, in particular, implies that it’s not so easy to put members into a union with copies of custom copy constructors and destructors. With std::variant
there are no such restrictions.std::optional
, is surprisingly useful and in practice provides capabilities that exist in many functional languages. 'optional'
is an object that may or may not contain values; this object is convenient to use as the return value of a function when it cannot return a value; then it serves as an alternative, for example, to a null pointer.optional
, we gain an additional advantage: now the possibility of a function failure is clearly indicated directly in the declaration, and, since we have to extract a value from optional, the probability that we accidentally use a zero value is significantly reduced.optional
, the function leaves this possibility: an invalid string can be passed, which cannot be converted. The caller uses the value_or
function to get the value from optional
, and if the function fails, it returns the default value of zero (if the conversion failed). #include <experimental/optional> using namespace std::experimental; optional<int> convert(const std::string& s) { try { int res = std::stoi(s); return res; } catch(std::exception&) { return {}; } } int v = convert("123").value_or(0); std::cout << v << std::endl; int v1 = convert("abc").value_or(0); std::cout << v1 << std::endl;
std::any
, which provides a type-safe container for a single value of any type (provided that it has a constructor when copying). You can check whether any contains any value and extract this value with std::any_cast
, like this: #include <experimental/any> using namespace std::experimental; std::vector<any> v { 1, 2.2, false, "hi!" }; auto& t = v[1].type(); // std::any? if (t == typeid(double)) std::cout << "We have a double" << "\n"; else std::cout << "We have a problem!" << "\n"; std::cout << any_cast<double>(v[1]) << std::endl;
type()
member to get a type_info
object that says what is contained in any
. An exact match between the types is required, otherwise the program will throw an exception std::bad_any_cast
: try { std::cout << any_cast<int>(v[1]) << std::endl; } catch(std::bad_any_cast&) { std::cout << "wrong type" << std::endl; }
void*
, but in this case type safety is guaranteed. For example, you may need different representations of the base value: say, represent '5' both as an integer and as a string. Such cases are common in interpreted languages, but can be useful in cases where a representation is required that will not be automatically converted.Source: https://habr.com/ru/post/345560/
All Articles