c++templatestemplate-specializationmisraexplicit-specialization

Do template specialized class with static methods occupy storage?


(I am sorry for the messy title. I will gladly accept suggestions to improve it.)

I will try to be as straightforward as possible. I have the folowing code:

file1.hpp

template <class val_t>
struct MatOps;

file2.hpp:

#include "file1.hpp"
template <> struct MatOps<float>{
  static void method1(){
    // Do something
  }
  static void method2(){
    // Do something
  }
  static void method3(){
    // Do something
  }
}

File3.hpp:

#include "file1.hpp"
template <> struct MatOps<double>{
  static void method1(){
    // Do something different
  }
  static void method2(){
    // Do something different
  }
  static void method3(){
    // Do something different
  }
}

main.cpp

#include "file2.hpp"
#include "file3.hpp"

int main(){
  float a,b,c,d;

  MatOps<float>::method1(a,b,...);
  MatOps<float>::method2(c,d,...);

  return 0;
}

Questions:

  1. I am not using the explicit specialization MatOps<double>. However, is MatOps<double> actually instantiated? Or more roughly: does the inclusion of file3.hpp occupy any storage whatsoever?
  2. I am not using MatOps<float>::method3(), but I am using the other methods in the class. Since I am explicitely using MatOps<float>, does the compiler generate code for MatOps<float>::method3()?

Rationale: I have been asked to follow some guidelines in the MISRA C++:2003 standard. Although obsolete, I have been encouraged to use whatever is reasonable in there. In particular, there is a rule that reads:

Header files should be used to declare objects, functinos, inline functions, function templates, typedefs, macros, classes, and class templates and shall not contain or produce definitions of objects or functions (or fragments of functions or objects) that occupy storage.

A header file is considered to be any file that is included via the #include directive, regardless of name or suffix.

My code is heavily templated and hence I can include any files according to this rule. My problem comes when I do full specializations (I only do two of them: the ones listed in file2.hpp and file3.hpp). What are full template specializations? Is code generated for them even if they are not used? Ultimately, do they occupy storage?


Solution

  • To answer your first question, I quote the following from cppreference.com:

    A class template by itself is not a type, or an object, or any other entity. No code is generated from a source file that contains only template definitions. In order for any code to appear, a template must be instantiated: the template arguments must be provided so that the compiler can generate an actual class (or function, from a function template).

    Inclusion of file3.hpp will not result in code generation by itself.

    As for the second part, again from the same page,

    When code refers to a template in context that requires a completely defined type, or when the completeness of the type affects the code, and this particular type has not been explicitly instantiated, implicit instantiation occurs. For example, when an object of this type is constructed, but not when a pointer to this type is constructed.

    This applies to the members of the class template: unless the member is used in the program, it is not instantiated, and does not require a definition.

    Unless you are doing an explicit instantiation of your class template, individual member functions of your class template will not get instantiated, i.e., the compiler will not generate code for MatOps<float>::method3().