I'm trying to create the program that executes some code only if the template is instantiated (it will be used for low-level driver initialization). Now I have the following solution.
class Initializer
{
public:
Initializer(){
// This code is executed once
}
void silly() const{
}
};
template <class T>
class Proxy{
protected:
static const Initializer init;
};
template<class T>
const Initializer Proxy<T>::init;
template<class T>
class MyTemplate : public Proxy<void>{
public:
static void myMethod1(){
init.silly();
// ... Something useful
}
static void myMethod2(){
init.silly();
// ... Something useful
}
};
The Initializer
default constructor is executed only in case I call myMethod1()
or myMethod2()
somewhere.
But is there a way to get rid of those init.silly();
lines?
template and low-level driver initialization?.. I'd try to make it as C as possible :) to ensure exact behavior.
You can do something like this perhaps:
All your code uses only static functions and doesn't really show why you would use classes and templates. With my change I made
myMethod1
andmyMethod2
non static and Proxy() constructor would createInitializer
once.Note that because of all that template mess your
Initializer
might be executed as many times as you instantiate Proxy template. Did you really mean it? If not, convert to clear readable code that doesn't have this unexpected results. This will also be better maintainable and readable for others:This makes it absolutely clear that
Initializer
will be created only once just beforemyMethod1
ormyMethod2
is called. If nothing calls yourInitializer::init
then that code fromInitializer
should be removed at link time.Your problem, is that members of a template are not instantiated unless they are referenced.
Rather than calling
init.silly()
, you can just reference the member:Or, if you want
init
to be defined absolutely always, you can explicitly instantiate it: