Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

trying to force static object initialization

I am trying to initialize a static object without success. The purpose is to automatically register a factory class in a repository (which is a singleton).

I've already had a look at: How to force a static member to be initialized?

One of the comments says that (there is also an example that I've followed):

I read it up in the C++ standard (14.7.1): Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist; in particular, the initialization (and any associated side-effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.

So I'm trying to do something similar but I haven't manage to force the object initialization. Here is the code. I don't know what I'm missing. This is the template I'm using.

namespace my_lib
{
    template <typename T>
    struct FactoryHelper
    {
        FactoryHelper ();
        static FactoryHelper<T> _helper;
    };
}

And this is the macro that the user of the library would use to define the factory class and, at the same time, register an object in the repository:

#define CREATE_FACTORY(ClassName)\
namespace my_lib\
{\
    class ClassName##Factory;\
    template<> FactoryHelper<ClassName##Factory>::FactoryHelper () { std::cout << "object initialized!" << std::endl; }\
    template<> FactoryHelper<ClassName##Factory> FactoryHelper<ClassName##Factory>::_helper;\
    struct ClassName##Factory : public FactoryBase<ClassName> {\
      ...\
    };\
} 

The previous code is defined in a header file (Factory.h).

In a .cpp file (Example.cpp), I have:

CREATE_FACTORY(UnitTestExample)
...

When I execute the program, I cannot see the message that the constructor prints when it is invoked. Any help is more than welcome.

Thanks in advance.

like image 417
user1192525 Avatar asked Mar 03 '12 20:03

user1192525


1 Answers

This is a tricky area of C++. What you've done is to try to define the static member here:

template<> FactoryHelper<ClassName##Factory> FactoryHelper<ClassName##Factory>::_helper;\

but this is actually a declaration and not a definition. For C++ to treat it as a definition you have to pass something to the constructor. Typically, this is the value you want to initialize it to:

template<> FactoryHelper<ClassName##Factory> FactoryHelper<ClassName##Factory>::_helper = FactoryHelper<ClassName##Factory>();\

But in your case, you want this to be a singleton, so you probably don't want it to be copyable. In that case, you need some dummy parameter:

template<> FactoryHelper<ClassName##Factory> FactoryHelper<ClassName##Factory>::_helper(0);\

and you have to modify your constructor appropriately:

template<> FactoryHelper<ClassName##Factory>::FactoryHelper (int) { std::cout << "object initialized!" << std::endl; }\

Here is the complete working example:

#include <iostream>

namespace my_lib
{
    template<typename> struct FactoryBase { };
    template <typename T>
    struct FactoryHelper
    {
        FactoryHelper (int);
        static FactoryHelper<T> _helper;
    };
}

#define CREATE_FACTORY(ClassName)\
namespace my_lib\
{\
    class ClassName##Factory;\
    template<> FactoryHelper<ClassName##Factory>::FactoryHelper (int) { std::cout << "object initialized!" << std::endl; }\
    template<> FactoryHelper<ClassName##Factory> FactoryHelper<ClassName##Factory>::_helper(0);\
    struct ClassName##Factory : public FactoryBase<ClassName> {\
    };\
} 

struct UnitTestExample {
};

CREATE_FACTORY(UnitTestExample);

int main(int argc,char **argv)
{
  return 0;
}

That said, using some of the suggestions in the other answers may be a better design decision.

More information on the explicit specialization declaration vs. definition can be found here: static member initialization for specialized template class

like image 174
Vaughn Cato Avatar answered Nov 03 '22 01:11

Vaughn Cato