Main Content

AUTOSAR C++14 Rule A13-3-1

A function that contains "forwarding reference" as its argument shall not be overloaded

Since R2021a

Description

Rule Definition

A function that contains "forwarding reference" as its argument shall not be overloaded.

Rationale

Suppose that you define a template function func with a forwarding reference parameter T&& like this:

template <typename T> void func(T&& param) {}
Suppose that you overload this template function with another function:
void func(int param) {}
When the function func is called, it is difficult to tell whether the call resolves to the template function or the overload, without working through the intricacies of the overload resolution mechanism. A developer or reviewer can easily mistake which function is called after the overload resolution. For instance, the function call:
short var;
//...
func(var);
resolves to the template function because it is an exact match after template instantiation, but a developer or reviewer might think that the overload is called because the type short promotes to int.

To avoid this issue, do not overload on template functions that take forwarding references. For template constructors, you can constrain the constructors to not match the overloads (using std::enable_if). When constrained this way, there is no scope for confusion between the template constructor and its overloads.

Polyspace Implementation

The checker flags definitions of template functions that contain forwarding references (template parameters with type T&&) if those functions are also overloaded. Events below the checker result show the locations of the overloads. If an overload is an implicitly defined member function such as a constructor, the corresponding event points to the containing class.

The checker shows you all template functions with forwarding references that are overloaded. If you determine that an overload cannot cause confusion, add a comment to your result or code to avoid another review. See Address Results in Polyspace User Interface Through Bug Fixes or Justifications or Address Results in Polyspace Access Through Bug Fixes or Justifications (Polyspace Access).

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

expand all

#include <cstdint>

template <typename T> 
void func(T&& t) noexcept(false) //Noncompliant
{                                 
}

void func(
  std::int32_t&& t) noexcept
{
}

In this example, the function func(std::int32_t &&) overloads the template function with the same name, and violates the rule.

#include <type_traits>

class A
{
public:
	template<typename T>
	A(T &&value) {} //Noncompliant
};

class B
{
public:
	template<typename T,
	std::enable_if_t<! std::is_same<std::remove_cv_t<
	std:: remove_reference_t<T>>, B>::value> * = nullptr>
	B(T &&value) {} //Compliant
};

A getObjA();
B getObjB();

void func() {
	A objA = getObjA();
	B objB = getObjB();
}

In this example, class A has a template constructor that is overloaded by the implicit move constructor of class A. The overloading violates the rule.

Class B circumvents this problem by constraining the template constructor to not match the implicit constructor. In this example, the implicit constructor move constructor is called when the function getObjB returns an object of type B.

Check Information

Group: Overloading
Category: Required, Automated

Version History

Introduced in R2021a

expand all