core: NS_OBJECT_TEMPLATE_CLASS_DEFINE doesn't play nice with namespaces

... and I have no idea of how to make it work.

Explanation. I have a templated class, in a namespace.

I need to do something like:

namespace myrouting
{
NS_LOG_COMPONENT_DEFINE("MyRoutingRoutingProtocol");

NS_OBJECT_TEMPLATE_CLASS_DEFINE(MyRoutingRoutingProtocol, Ipv4RoutingProtocol);
NS_OBJECT_TEMPLATE_CLASS_DEFINE(MyRoutingRoutingProtocol, Ipv6RoutingProtocol);

This throws all the possible errors, because some functions expanded from the macro are inside the namespace.

I tried to do something like

#define NS_OBJECT_TEMPLATE_CLASS_NAMESPACE_DEFINE(namespace, type, param)                          \
    template class type<param>;                                                                    \
    template <>                                                                                    \
    std::string DoGetTemplateClassName<type<param>>()                                              \
    {                                                                                              \
        return std::string("ns3::") + std::string(#namespace) + std::string("::") +                \
               std::string(#type) + std::string("<") + std::string(#param) + std::string(">");     \
    }                                                                                              \
    static struct Object##namespace##type##param##RegistrationClass                                \
    {                                                                                              \
        Object##namespace##type##param##RegistrationClass()                                        \
        {                                                                                          \
            ns3::TypeId tid = type<param>::GetTypeId();                                            \
            tid.SetSize(sizeof(type<param>));                                                      \
            tid.GetParent();                                                                       \
        }                                                                                          \
    }                                                                                              \
    Object##namespace##type##param##RegistrationVariable

but I still get an error: error: no function template matches function template specialization 'DoGetTemplateClassName' NS_OBJECT_TEMPLATE_CLASS_NAMESPACE_DEFINE(myrouting, MyRoutingRoutingProtocol, Ipv4RoutingProtocol); because (of course) the DoGetTemplateClassName function is in the ns3::myrouting namespace, and the template specialization is in the ns3 namespace

This might not be a dramatic issue in my case, as the class won't use TypeId(GetTemplateClassName<MyRoutingRoutingProtocol<Ipv4RoutingProtocol>>()) (I prefer to use Ipv4MyRoutingRoutingProtocol).

Still, it's a heavy limitation.

Note: if we remove the DoGetTemplateClassName everything works as expected.

Edited by Tommaso Pecorella