MISRA C++:2023 Rule 28.6.2
Description
Rule Definition
Forwarding references and std::forward
shall be used
together.
Rationale
You typically use a forwarding reference parameter, which is a
parameter of type T &&
, in function
templates to forward the parameter to other functions while
preserving the value category, such as lvalue or rvalue, and
constness of the parameter.
Forwarding references use complex C++ language features that can
be difficult to master. Wrapping a forwarding reference parameter in
a call to the function std::forward<T>
can
make your intent clearer and to avoid unintended code
behavior.
Forwarding references use advanced C++ language features such as:
Type deduction, to obtain the type of the forwarding reference based on the argument passed to the function.
Reference collapsing, to preserve the original value category of the forwarded reference.
Polyspace Implementation
The coding rule checker reports a violation if one of these is true:
You forward a forwarding reference parameter without wrapping the parameter in a call to the function
std::forward<T>
.You wrap a forwarding reference parameter in a call to
std::move<T>
or you wrap an rvalue reference in a call tostd::forward<T>
.The function
std::forward<T>
is instantiated with a type that does not match the type of the forwarded reference parameter.
For example, in this code snippet, the func
template function takes a forwarding reference and passes it to the
function otherFunc
. The first call to
otherFunc
is noncompliant because it uses
std::move<T>
instead of
std::forward<T>
. The second call to
otherFunc
is noncompliant because
std::forward<T>
is instantiated with a
float
, which does not match the type of the
forwarded variable, an
int
.
#include <iostream>
#include <utility>
void otherFunc(int && var)
{
std::cout << "Forwarded rvalue: " << var << "\n";
}
template <typename T>
void func(T && fwdref)
{
otherFunc(std::move(fwdref)); // Noncompliant
otherFunc(std::forward<float>(fwdref)); // Noncompliant
}
void main()
{
func(42);
}
Polyspace® does not report a violation if no forwarding takes
place. For example, in this code snippet,
std::forward<T>
is not used with
forwarding references. Polyspace does not consider this incorrect
use of std::forward<T>
a
violation.
class myClass
{
};
void func(myClass &lval, myClass &&rval)
{
const myClass &var1 = std::forward<myClass>(lval); // Compliant
const myClass &var2 = std::forward<myClass>(rval); // Compliant
}
Troubleshooting
If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.
Examples
Check Information
Group: Algorithms library |
Category: Required |
Version History
Introduced in R2024b