Run code once for each instance of a C ++ class template

Ok, this is a tough question.

I have a C ++ class template that runs multiple times. For each of these instances, I need to execute a function that registers some operators. This needs to be done only once for a template instance before the first object of this template instance is used (which does not mean that it must be executed during instanciation that occurs during compilation).

So far, I have done this manually. But it is a pain. Therefore, I would like to automatically perform the registration function.

My current idea is to call a secure registration method in the constructor. However, with each instance of the class, it requires (small) overhead. Since this is done very often, I would like to avoid this overhead.

I also tried to use the static RAII helper element, but the static members of the template class were not constructed if they were not actively available, so this attempt failed.

Is there a way to execute code when initializing a class template (by a function or maybe a helper class RAII) without runtime overhead?

+5
source share
1 answer

You can add a static data item that will do everything that is needed in its constructor and destructor. You can safely put your definition in the header file, because until it is created, it will be defined only once. The only catch is that you must odr-use it to create it.

template <typename T> class Data { public: Data() { std::cout << "creating Data<" << typeid(T).name() << '>' << std::endl; } ~Data() { std::cout << "destroying Data<" << typeid(T).name() << '>' << std::endl; } }; template<typename T> class A { static Data<T> data; public: A() { // this is necessary for data to be instantiated (void)data; } }; // This also should be in a header template<typename T> Data<T> A<T>::data; int main(){ A<int> aInt; A<int> aInt2; A<float> aFloat; } 

Demo

EDIT: this is actually a bit unsafe, because the order of creating static objects in different translation units is unspecified, therefore, for example, at the time of exelucion Data::Data() there cannot be std::cout (so do not use any static global objects). A safer approach is to call a static function in A::A() , although it introduces some overhead:

 template<typename T> class A { static void createData() { static Data<T> data; } public: A() { createData(); } }; 
+6
source

Source: https://habr.com/ru/post/1204540/


All Articles