I want to dispatch functions based on user defined "tag" of my input types. For example, I defined a tag called SomeSpecificObjectType
and in class Object
I mark this class as a SomeSpecificObjectType
.
struct SomeSpecificObjectType{};
template<typename T>
class Object
{
public:
Object(T&&in): m_data(in){};
typedef SomeSpecificObjectType ObjectTag;
T m_data;
};
Now I have another object, which doesnt share this tag. So I dont touch it.
template<typename T>
class OtherObject
{
public:
OtherObject(T&&in): m_data(in){};
T m_data;
};
Now I define a struct to check for the tag I defined above.
template<typename T, typename Enable=void>
struct is_some_specific_object_type
{
static constexpr bool value = false;
};
template<typename T>
struct is_some_specific_object_type<T, typename std::enable_if<std::is_same<typename T::ObjectTag, SomeSpecificObjectType>::value>::type>
{
static constexpr bool value = true;
};
My functions:
template<typename T, typename std::enable_if<!is_some_specific_object_type<T>::value>::type* = nullptr>
void some_func(const T & data)
{
std::cout <<"something" <<std::endl;
}
template<typename T, typename std::enable_if<is_some_specific_object_type<T>::value>::type* = nullptr>
void some_func(const T & data)
{
std::cout <<"something else" << std::endl;
}
This seems work.
However, imagine I have class where its definition is hidden from me (HiddenObject
) - this means I am unable to just add the "tag" SomeSpecificObjectType
to this class. Essentially I want is_some_specific_object_type::value == true
for this HiddenObject
. Is there a way to do it without edditing the class HiddenObject
template<typename T>
class HiddenObject
{
public:
HiddenObject(T&&in): m_data(in){};
T m_data;
};
Final desired result:
int main()
{
Object obj(123);
OtherObject o_obj(123);
some_func(obj);
some_func(o_obj);
//HiddenObject h_obj(123);
//some_func(h_obj); ---> print "something else"
return 0;
}
Eddit: Someone didnt like I used the word "trait", I will repalce this word with Tag, seems more fitting to avoid confusion.
Just add specialization of is_some_specific_object_type
for HiddenObject
:
template <typename T> struct is_HiddenObject : std::false_type {};
template <typename T> struct is_HiddenObject<HiddenObject<T>> : std::true_type {};
template<typename T>
struct is_some_specific_object_type<T, std::enable_if_t<is_HiddenObject<T>::value>> : std::true_type{};
Notice that you might have to add/rearrange the specializations if your type (HiddenObject
) matches several specializations.