New standard library features in Visual C++ 2017 RC

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.
    std::any value{ 10 };   // int 10
    value = 10.0;           // double 10.0
    value = "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.
    auto 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;
       else
          std::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.
    std::variant<int, double, std::string> value;
    value = 10;    // int 10
    value = 10.0;  // double 10.0
    value = "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 2
    
    std::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:
    using 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.

    auto 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.
vclangsettings

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.