The new Visual C++ 2017, currently in release candidate phase, provides a series of updates and fixes to both the C++ compiler and the standard library. A comprehensive list of these improvements is available at What’s New for Visual C++ in Visual Studio 2017 RC.
In this article, I want to shortly look at the new standard library features from VC++ 2017.
- std::any (available in header <any>) is a class that represents a type-safe container that can hold the value of any copy-constructible object. To read the value stored in an any variable you need to use the non-member function std::any_cast.
12345678910111213std::any value{ 10 }; // int 10value = 10.0; // double 10.0value = "10"s; // string "10"if(value.has_value()){if (value.type() == typeid(std::string)){std::cout << "value="<< std::any_cast<std::string>(value)<< std::endl;}}
- std::optional (available in header <optional>) is a class template that may or may not contain a value any moment in time. If it contains a value, it is allocated as part of the optional object, and therefore does not incur any memory overhead.
1234567891011121314151617181920212223242526auto string_part(std::string const & text,std::optional<int> start,std::optional<int> end){auto s = start.value_or(0);auto e = end.value_or(text.length());return text.substr(s, e - s);}auto lprint = [](auto const & value){if (value.has_value())std::cout << *value << std::endl;elsestd::cout << "[no value]" << std::endl;};std::optional<int> value;lprint(value);value = 10;lprint(value);std::cout << string_part("marius"s, {}, {}) << std::endl; // prints "marius"std::cout << string_part("marius"s, {1}, {4}) << std::endl; // prints "ari"
- std::variant (available in header <variant>) is a class template that represents a type-safe union. A variant can hold any number of alternatives, but they cannot be of type reference, array or void. The first alternative must be default constructible, because variants are default constructible and a default-constructed variant object contains a value of its first alternative. If the first alternative is not default-constructible, std::monostate (an empty, default-constructible class) can be used for that purpose. If it contains a value, it is allocated as part of the variant object, and therefore does not incur any memory overhead.
12345678910std::variant<int, double, std::string> value;value = 10; // int 10value = 10.0; // double 10.0value = "10"s; // string "10"std::cout << std::get<std::string>(value) << std::endl; // prints "10"std::cout << std::get<2>(value) << std::endl; // prints "10"std::cout << "index = " << value.index() << std::endl; // prints 2std::visit([](auto&& arg) {std::cout << arg << std::endl; }, value);
- std::basic_string_view (available in header <string_view>) is a class template that represents a view of a contigous sequence of characters (defined by a pointer to the start of the sequence and a count). Several type aliases are available:
1234using string_view = basic_string_view<char>;using u16string_view = basic_string_view<char16_t>;using u32string_view = basic_string_view<char32_t>;using wstring_view = basic_string_view<wchar_t>;
basic_string_view has an interface almost identical to basic_string so that switching from the later is as simple as possible. A typical useage of this class template is for function parameters as a replacement for constant references to basic_string.
123456789101112auto string_part(std::string_view text,std::optional<int> start,std::optional<int> end){auto s = start.value_or(0);auto e = end.value_or(text.length());return text.substr(s, e - s);}std::cout << string_part("marius"s, {}, {}) << std::endl;std::cout << string_part("marius"s, { 1 }, { 4 }) << std::endl;
Additional new supported C++17 standard library features are:
- std::apply is a function template that invokes a specified callable object with a tuple of arguments.
- std::make_from_tuple is a function template that creates an object by invocking its constructor with the members of a specified tuple.
To have all these available the /std::c++latest compiler switch must be used. This can be also set from the project properties, at C/C++ > Language > C++ Language Support.