This is a draft version of a MISRA C++ 202x rule proposed for public review.
MISRA Rule 28.6.2
Category: Required
Analysis Type: Decidable,Single Translation Unit
Amplification
A forwarding reference parameter (of type T &&
) shall be forwarded when passed to other functions by wrapping the
parameter in a call to the function std::forward< T >
.
Furthermore, std::forward
shall only be used to forward a forwarding reference.
Rationale
Perfect forwarding relies on language features such as reference collapsing and type deduction which are complex to master. Enforcing the use of
well known idioms avoids the risk of writing code that does not do what was intended.
Note: care must be taken not to forward the same argument twice — see M23_280: MISRA C++ 2023 Rule 28.6.3.
Example
void f1( std::string & ); // #1
void f1( std::string && ); // #2
template< typename T1, typename T2 >
void f2( T1 && t1, T2 & t2 )
{
f1( t1 ); // Non-compliant - calls #1
f1( std::forward< T1 >( t1 ) ); // Compliant - calls #1 (for #4) or #2 (for #3)
f1( std::forward< T2 >( t2 ) ); // Non-compliant - calls #2
f1( std::forward< T2 >( t1 ) ); // Non-compliant - wrong template parameter
f1( std::move( t1 ) ); // Non-compliant - calls #2
f1( std::move( t2 ) ); // Rule does not apply - calls #2
auto lambda = [] ( auto && t )
{ f1(t); }; // Non-compliant - calls #1
}
void f3()
{
std::string s;
f2( std::string { "Hello" }, s ); // #3
f2( s, s ); // #4
}
template< typename T >
struct A
{
void foo( T && t )
{
std::move( t ); // Rule does not apply - not a forwarding reference
}
};
Copyright The MISRA Consortium Limited © 2023