Main Content

AUTOSAR C++14 Rule A8-2-1

When declaring function templates, the trailing return type syntax shall be used if the return type depends on the type of parameters

Since R2020a

Description

Rule Definition

When declaring function templates, the trailing return type syntax shall be used if the return type depends on the type of parameters.

Rationale

When the return type of a template depends on the types of parameters, using the trailing return type syntax improves readability of the code significantly.

For instance, for out-of-class definitions of methods, using the trailing return type syntax means that you do not have to use the fully qualified return type of a function along with the typename keyword. Instead of explicitly specifying the fully qualified return type for aMethod in this example:

template <typename T>
class aClass {
    public:
      using vectorType = std::vector<T>;
      vectorType aMethod(T const&);
};

//Difficult-to-read method definition
//Part in bold indicates fully qualified return type of method
template <typename T>
typename aClass<T>::vectorType aClass<T>::aMethod(T const &) {
};
You can use the trailing return type syntax:
template <typename T>
class aClass {
    public:
      using vectorType = std::vector<T>;
      vectorType aMethod(T const&);
};
template <typename T>
auto aClass<T>::aMethod(T const &) -> vectorType {
};

Polyspace Implementation

The checker flags function template declarations where the explicitly specified return type of a template function has the same scope as the template function itself.

For instance, in the preceding example, the function aMethod has a return type vectorType, which has the same scope as aMethod, namely the class aClass<T>. Instead of explicitly specifying the fully qualified return type, you can use the trailing return type syntax.

Because C++14 has enabled return-type deduction, you can use the auto keyword to declare generic templates while omitting the trailing return type. In such cases, Polyspace® does not raise a violation.

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 <vector>
#include<cstdint>

template<class T, class U>
decltype(std::declval<T>() * std::declval<U>()) 
bar(T const& lhs, U const& rhs) {// Noncompliant
  return lhs * rhs;
}

template<class T, class U>
auto foo(T a, U b) -> decltype(a*b){        //Compliant
  return a*b;
}
template<class T, class U>
auto foo2(T a, U b) {        //Compliant
  return a*b;
}

In this example, three generic function templates are declared:

  • The template bar explicitly defines the return-type. Such declarations are difficult to read and understand. Polyspace flags the declaration.

  • The template foo uses the keyword auto, and then specifies a trailing return-type. Such declarations are easy to read and understand. Polyspace does not flag the declaration.

  • The template foo2 uses the keyword auto but omits the trailing return-type. From C++14 onward, the compiler can deduce the return type of such templates. Polyspace does not flag the declaration.

Check Information

Group: Declarators
Category: Required, Automated

Version History

Introduced in R2020a