Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative to using helper function to store a static variable for a template function?

I have a function which can be simplifed as:

template<typename T>
void my_function(T value_in)
{
   static int my_number{};
   // Do stuff with my_number and value_in
   my_number++;
}

What I want is for my_number to increment on each function call. This would work as I expect if this was not a templated function, however, the behavior of this is not as expected due to multiple functions being generated (at compile time? is generated the proper term?) based on T's type when calling this function elsewhere in my project.

Currently, my solution is to do something like this:

int static_number_incrementer()
{
   static int static_number{};

   return static_number++;
}

template<typename T>
void my_function(T value_in)
{
   int my_number = static_number_incrementer();
   // Do stuff with my_number and value_in
}

This works, but I'm wondering if there is something more "built-in" that I can use in the original implementation of my_function that doesn't require creating a second function?

like image 751
cam.b Avatar asked Oct 31 '25 07:10

cam.b


1 Answers

As you already noticed, different template realizations of my_function are different functions. Since the number of calls has to be stored somewhere, this cannot be inside the template function. A very proper way to do it is, as suggested in the comments, to place this information inside a class. At minimum, you could transform your function to a struct with an operator() inside. Something like

// my_function.hpp
struct my_function {
   template <typename T>
   void operator()(T value_in);

private:
   static int static_number;
};

// my_function.cpp
int my_function::static_number = {};

Notice that before c++17 the private static member static_number must be initialized in a separate cpp source file. Within c++17 you can declare the static member static_number as inline, initializing it directly in the class declaration, thus without the need of an additional cpp source code:

// my_function.hpp
// Requires c++17
struct my_function {
   template <typename T>
   void operator()(T value_in);

private:
   inline static int static_number = {};
};

The you call your function with syntax similar to the case of a "normal" function.

my_function{}(x);

Since static_number is static, there is a single static_number for all instancies of my_function. This approach has the benefit that static_number is not accessible from outside.

An alternative solution to yours, is to have a global variable, perhaps "hidden" inside a namescope, so to avoid clashes:

namespace impl {
   int static_number = {};
}

This has however the drawback that static_number is accessible from functions other than my_function.

like image 77
francesco Avatar answered Nov 02 '25 20:11

francesco