These articles are written by Codalogic empowerees as a way of sharing knowledge with the programming community. They do not necessarily reflect the opinions of Codalogic.
Originally auto
was a largely superfluous keyword that you could
forget about without any great loss. In fact in C++11 its original
meaning was deprecated. But as each new C++ standard comes out
auto
plays a bigger and bigger role.
Below is a program that shows most of its modern uses (see https://godbolt.org/z/n3Tfnz54s). I'm hoping the comments provide sufficient explanation.
#include <iostream>
#include <string>
#include <tuple>
#include <concepts>
// C++ 11 - placeholder type specifier - the variable type is deduced from the initializer
auto i = 10;
auto f = 2.2;
// C++11 - trailing return type
auto f1() -> int
{
return 0;
}
// C++14 - The return type is deduced from the operand of its first return statement
auto f2()
{
return 0;
}
// C++17 - in a structured binding declaration
/*Given a function*/ auto x1() { return std::tuple{ 1, 2.2 }; }
void f3()
{
auto [a, b] = x1();
std::cout << __FUNCTION__ << ": a = " << a << ", b = " << b << "\n";
}
// Called with: f3(); - Output is: f3: a = 1, b = 2.2
// C++17 - in the parameter declaration of a non-type template parameter
// where the template argument is a value not a type
template<auto V>
void f4()
{
std::cout << __FUNCTION__ << ": " << V << "\n";
}
// Called with: f4<12>(); - Output is: f4: 12
// Called with: f4<2.5>(); - Output is: f4: 2.5
// C++20 - Abbreviated function template - An alternative template notation
// Equivalent to: template< typename T > void f5( T t )
void f5( auto t )
{
std::cout << __FUNCTION__ << ": " << t << "\n";
}
// Called with: f5( 12 ); - Output is: f5: 12
// Called with: f5( 2.5 ); - Output is: f5: 2.5
// C++20 - In concepts - The concept is specified before 'auto'
void f6( std::integral auto i )
{
std::cout << __FUNCTION__ << ": " << i << "\n";
}
// Called with: f6( 10'200'300'400ll ); - Output is: f6: 10200300400
// Can't acll with f6( "test" ); // std::integral concept prevents this
// In C++23 - To create a new temporary variable
/*Given a function*/ void x2( int & a ) { ++a; }
/*Given a function*/ void x3( int && a ) { ++a; }
void f7()
{
int a = 1;
x2( a ); // a is incremented
std::cout << __FUNCTION__ << ": " << a << " ";
x3( auto{a} ); // A temporary is passed to x3() so a is not incremented
std::cout << a << "\n";
}
// Called with: f7(); - Output is: f7: 2 2
// In C++23 - To derive a type based on an expression
/* Not implemented yet
void f8( auto a, auto b )
{
std::cout << auto{a + b}( 7.5 );
}
*/
int main()
{
f1();
f2();
f3();
f4<12>();
f4<2.5>();
f5( 12 );
f5( 2.5 );
f6( 10'200'300'400ll ); // Using C++14 digit separator
//f6( "test" ); // std::integral concept prevents this
f7();
}
The output is:
f3: a = 1, b = 2.2
f4: 12
f4: 2.5
f5: 12
f5: 2.5
f6: 10200300400
f7: 2 2
February 2023
January 2023
December 2022
November 2022
October 2022
September 2022
August 2022
November 2021
June 2021
May 2021
April 2021
March 2021
October 2020
September 2020
September 2019
March 2019
June 2018
June 2017
August 2016