Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute code once for each C++ class template instance

Ok, this is a complicated one.

I have a C++ class template that is instanciated many times. For each of these instances I need to execute a function that register some operators. This needs to be done only once per template instance before the first object of that template instance is used (which does not mean it must be executed at instanciation which happens during compile time).

Up to date I did this manually. But it is a pain. So I would like to execute the registration function automatically.

My current idea is to call a guarded registration method in the constructor. However this requires a (small) overhead whenever an instance of the class is contructed. Since this is done very often I would like to avoid that overhead.

I also tried to use a static RAII helper member but static template class members are not constructed if they are not actively accessed so this try failed.

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

like image 694
Silicomancer Avatar asked Oct 13 '14 07:10

Silicomancer


People also ask

What is Oops template function?

Function Template A function template is a generic function that is defined on a generic type for which a specific type can be substituted. Compiler will generate a function for each specific type used. Because types are used in the function parameters, they are also called parameterized types.

How are C++ templates compiled?

Instantiation is the process by which a C++ compiler creates a usable function or object from a template. The C++ compiler uses compile-time instantiation, which forces instantiations to occur when the reference to the template is being compiled.

What is the task of compile while handling template?

When you call a function template, the compiler tries to deduce the template type. Most of the time it can do that successfully, but every once in a while you may want to help the compiler deduce the right type — either because it cannot deduce the type at all, or perhaps because it would deduce the wrong type.

What is member function template explain with example?

Member function templates are template functions that are members of a class or class template. Member functions can be function templates in several contexts. All functions of class templates are generic but are not referred to as member templates or member function templates.


1 Answers

You can add a static data member which will perform whatever is needed in its constructor and destructor. You can safely put its definition into a header file because as long as it's template, it will be defined only once. The only catch is that to instantiate it you have to odr-use 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 creation of static objects in different translation units is unspecified, so for example there may be no std::cout at the moment of exetucion of Data::Data() (so don't use any static global objects there). A safer approach is to call a static function in A::A(), though it introduces some overhead:

template<typename T>
class A {
    static void createData() {
        static Data<T> data;
    }
public:
    A() {
        createData();
    }
};
like image 76
Anton Savin Avatar answered Oct 20 '22 21:10

Anton Savin