Static variable of template function

I have a template function to pass me a unique identifier based on the passed to it typename, for example:

template<typename T>
inline std::size_t get_component_type_id() noexcept
{
    static_assert(std::is_base_of<Component, T>::value, "T must be of type Component.");

    static size_t uniqueComponentId{__INTERNAL__::getUniqueComponentId()};

    return uniqueComponentId;
}

When I call get_component_type_idto BaseClass10 times, I get the same identifier. This works great.

However, I want to get the same identifier if I pass a child class to this function. When I call it with ChildClass, I get a different identifier. Why is this?

+4
source share
3 answers

You can try adding a function that calls get_component_type_id()with Componentas a template argument when the actual Tis a child Component.

template<class T>
auto fn() noexcept
{
    using type = std::conditional_t<std::is_base_of<Component, T>::value, Component, T>;
    return get_component_type_id<type>();
}
+4

, . .

PS: , : CppCon 2015: ' " : C++" ". 6:00

+3

get_component_type_id<BaseClass> get_component_type_id<ChildClass> - . , static size_t uniqueComponentId, .

OP

Yes it is possible. You can use:

template <typename T>
inline std::size_t get_component_type_id(T*, std::false_type) noexcept
{
   static size_t uniqueComponentId{__INTERNAL__::getUniqueComponentId()};
   return uniqueComponentId;
}

inline std::size_t get_component_type_id(BaseClass*, std::true_type) noexcept
{
   static size_t uniqueComponentId{__INTERNAL__::getUniqueComponentId()};
   return uniqueComponentId;
}

template<typename T>
inline std::size_t get_component_type_id() noexcept
{
   static_assert(std::is_base_of<Component, T>::value, "T must be of type Component.");
   return get_component_type_id((T*)nullptr, typename std::is_convertible<T, BaseClass>::type{});
}

However, it is fragile. If you want to have the same behavior for another class derived from Component, you will need to make significant changes.

You will be better off using the member function virtual.

struct Component
{
   virtual size_t get_type_id() const = 0;
};

struct BaseClass : Component
{
   size_t get_type_id() const
   {
       static size_t uniqueComponentId{__INTERNAL__::getUniqueComponentId()};
       return uniqueComponentId;
   }
};

struct ChildClass : BaseClass {};

Now you can implement size_t get_type_id() constinheritance hierarchy at any level at your discretion.

+2
source

All Articles