I attended a C++17 presentation by Nicolai Josuttis last year, but at the time, my laptop’s compiler didn’t support any of the features to try them out. After a recent update, it turns out that many are now supported, so I’ve written a few unit tests using GTest.
The first feature I tried was the if initialiser. This feature looks a bit odd at first, because C++ programmers are so conditioned to seeing if statements containing a single condition. Allowing an initialiser statement as well
if ( initialiser; condition )
means that you can initialise a variable and test it on the same line. It also prevents the variable being used outside the scope of the if statement – this prevents accidental re-use if you subsequently mis-type a variable name.
auto return_int()
{
return 101;
}
TEST( Cpp17, if_initialiser )
{
// NB we can use i in the body of the if or the else
// Also, must have a variable name for the object to live in the whole statement
// (so must name locks taken, even if not used in the body, otherwise it's a temporary).
if ( auto i = return_int(); i < 100 )
{
EXPECT_TRUE( i < 100 );
}
else
{
EXPECT_TRUE( i >= 100 );
}
}
TEST( Cpp17, if_initialiser_with_map_insert)
{
std::map<int, std::string> my_map{ {42, "Hi" } };
if ( auto[it, inserted] = my_map.insert( std::make_pair(42, "Bye" ) ); !inserted )
{
// See also StructuredBindings for iterating over a map
auto& [key,value] = *it; // iterator is pair of key and value
EXPECT_EQ( 42, key );
EXPECT_EQ( "Hi", value );
value = "Bye"; // update the value
EXPECT_EQ( "Bye", my_map[42] );
// key = 43; // compile error! - cannot assign to const key-type
}
}
See also next post on C++17 Structured Bindings.
Pingback: C++17: structured bindings | musingstudio