Main Content

AUTOSAR C++14 Rule A14-5-1

A template constructor shall not participate in overload resolution for a single argument of the enclosing class type

Since R2021a

Description

Rule Definition

A template constructor shall not participate in overload resolution for a single argument of the enclosing class type.

Rationale

A template constructor can lead to confusion about which copy or move constructor is being invoked in a copy or move. For instance:

  • An implicit constructor might be invoked when you expect the template constructor to be used. An implicit copy or move constructor exists in the class because a template constructor does not prevent its definition.

  • The template constructor might be invoked when you expect an explicit constructor to be used. A template constructor might a better match than the explicit constructor when an overload is resolved.

Polyspace Implementation

The checker raises a violation when:

  • A class contains a template copy or move constructor but at least one copy or move uses the implicit constructor in the class.

    The violation is shown on the template constructor. Events associated with the result show the copy or move where an implicit constructor is invoked.

  • A class contains a template copy or move constructor and an explicit constructor but at least one copy or move uses the template constructor.

    The violation is shown on the template constructor. Events associated with the result show the copy or move where the template constructor is invoked and the explicit constructor definition.

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

class record
{
  public:
    template<typename T> 
    record(const T &);  /*Non-compliant*/
};

void lookup(record aRecord)
{
    record copyOfARecord {aRecord};   
}

In this example, when creating the object copyOfARecord from the object aRecord, a copy constructor must be invoked. The template constructor specialization, that is, record<record>(const record &), and the implicit constructor, that is, record(const record &) are equally good candidates for a copy constructor. When a function and a specialization are equally good matches in the overload resolution process, the function is preferred. In this case, the implicit constructor is called instead of the template constructor, but a developer or reviewer might expect otherwise.

class record
{
  public:
    record(const record &);
  
    template<typename T> 
    record(T &);  /*Non-compliant*/
};

void lookup(record aRecord)
{
    record copyOfARecord {aRecord};   
}

In this example, when creating the object copyOfARecord from the object aRecord, a copy constructor must be invoked. The template constructor specialization, that is, record<record>(record &) is a better match compared to the explicit constructor, that is, record(const record &). The template constructor is called instead of the explicit constructor, but a developer or reviewer might expect otherwise.

Check Information

Group: Templates
Category: Required, Automated

Version History

Introduced in R2021a