Main Content

AUTOSAR C++14 Rule A14-7-2

Template specialization shall be declared in the same file (1) as the primary template (2) as a user-defined type, for which the specialization is declared

Since R2020a

Description

Rule Definition

Template specialization shall be declared in the same file (1) as the primary template (2) as a user-defined type, for which the specialization is declared.

Rationale

Observing this rule avoids situations where the behavior is undefined. For instance, if a compiler sees a partial specialization of a template after it has instantiated the template, the behavior is undefined. If you specialize a template in the same file as the template, this situation is less likely to occur.

You can also easily extend compile-time interfaces through specialization since the template and its specialization are in the same file and part of the same translation unit. The same reasoning applies to the requirement that a template specialization must be in the same file as the type for which the template is specialized.

Polyspace Implementation

The checker checks each template specialization and raises a violation if:

  • The specialization is not in the same file as the template that is specialized.

  • The specialization is not in the same file as the definition of the user-defined type for which the template is specialized.

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

  • node_placements.h

    #ifndef NODE_PLACEMENTS_H 
    #define NODE_PLACEMENTS_H 
    #include <iostream> 
    struct placed_node 
    { 
        double x_coordinate; 
        double y_coordinate; 
    }; 
    
    template <typename T> 
    struct node_position 
    { 
        T place; 
        void set_pos (T val) { 
    
            place = val; 
        } 
            void output () { 
            std::cout << "The given data type is not a valid placement.\n"; 
        } 
    }; 
     
    
    template<> 
    struct node_position<placed_node> //Compliant 
    { 
        placed_node place; 
        void set_pos (placed_node val) { 
            place = val; 
        } 
        void output () { 
            std::cout << "The position of the node is at x = " << place.x_coordinate 
            << " and y = " << place.y_coordinate << '\n'; 
        } 
    }; 
    
     
    template <typename T, typename U> 
    struct node_distance 
    { 
        T node_1; 
        U node_2; 
        void output_distance () { 
    
            std::cout << "Inputs are not valid nodes\n"; 
        } 
    }; 
    
    
    #endif 
  • node_distance.cpp

    #include "node_placements.h" 
    #include <math.h>
    
    template<> 
    struct node_position<char> //Noncompliant (1) 
    { 
        char place; 
        void set_pos (char val) { 
        place = val; 
        } 
        void output () { 
        std::cout << "Please input a numerical value with the 'placed_node' type\n"; 
        } 
    }; 
    
    template<> 
    struct node_distance<placed_node, placed_node> //Noncompliant (2) 
    { 
        placed_node node_1; 
        placed_node node_2; 
        double dist; 
        void calc_dist () { 
            double x_diff = abs(node_2.x_coordinate - node_1.x_coordinate); 
            double y_diff = abs(node_2.y_coordinate - node_1.y_coordinate); 
            dist = sqrt(pow(x_diff,2.0) + pow(y_diff,2.0)); 
        } 
    	
            void output () { 
            std::cout << "The distance between the nodes is " << dist << '\n'; 
        } 
    }; 
    
     
    int main () { 
    
        node_position<int> first_pos; 
        first_pos.set_pos(3); 
        first_pos.output(); 
        placed_node node_1 = {3.5,6.5}; 
        node_position<placed_node> second_pos; 
        second_pos.set_pos(node_1); 
        second_pos.output(); 
        placed_node node_2 = {10.0, -7.3}; 
        node_distance<placed_node,placed_node> distance_measure = {node_1, node_2}; 
        distance_measure.calc_dist(); 
        distance_measure.output(); 
    } 

In this example:

  • You declare the base template node_position in node_placements.h. But the char type specialization of the template is declared in node_distance.cpp. Polyspace reports a violation of this rule.

  • You specialize the template node_distance for the user-defined type placed_node in node_distance.cpp. But the user-defined type placed_node is defined in node_placements.h. Polyspace reports a violation of this rule.

  • You declare the base template node_position and its specialization for placed_node type in the same file node_placements.h. Polyspace does not report a violation.

Check Information

Group: Templates
Category: Required, Automated

Version History

Introduced in R2020a