#include <iostream>
#include <map>

namespace detail {
    struct FuncPtrMap {
        friend struct FuncPtrRegisterer;
        typedef void(*FuncPtr)();
        static std::map<std::string, FuncPtr> const &getMap() {
            return getWritableMap();
        }
        
    private:
        // SIOF-proof singleton
        static std::map<std::string, FuncPtr> &getWritableMap() {
            static std::map<std::string, FuncPtr> theMap;
            return theMap;
        }
    };

    // Each static instance will register one function pointer
    struct FuncPtrRegisterer {
        FuncPtrRegisterer(FuncPtrMap::FuncPtr funcPtr, char const *funcName) {
            FuncPtrMap::getWritableMap().insert(std::make_pair(funcName, funcPtr));
        }
    };
}

// Public access to the function pointers map
typedef std::map<std::string, detail::FuncPtrMap::FuncPtr> FunctionPointersMap;
FunctionPointersMap const &gFunctionPointersMap = detail::FuncPtrMap::getMap();

#define DO_CAT(A, B) A##B
#define CAT(A, B) DO_CAT(A, B)

// Registering macro : defines a static registerer
// with a (hopefully) unique name.
#define REGISTER_FUNC(NAME) detail::FuncPtrRegisterer \
    CAT(fpreg, __COUNTER__) (&NAME, #NAME)


//
// Test
//

void myFunc1() {
    std::cout << "func1\n";
}
REGISTER_FUNC(myFunc1);

void myFunc2() {
    std::cout << "func2\n";
}
REGISTER_FUNC(myFunc2);

int main()
{
    for(FunctionPointersMap::const_iterator
        ite = gFunctionPointersMap.begin(),
        end = gFunctionPointersMap.end();
        ite != end; ++ite) {
        std::cout << "Calling " << ite->first << " : ";
        ite->second();
    }
    
    return 0;
}