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?
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.
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.
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.
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.
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();
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With