How can I specialized a template function to return true if objects belong to certain templates/classes and false for other templates/classes no classes have virtual functions. I have a template:
template<typename t1, typename t2, bool a> struct DynamicData{...}
which I want to do special processing, or any class derived from that template. in the following example I have a specialization of DynamicData<>
: DynamicDataSym<>
for which I did a specialization of is_dynamic<>
, but because DynamicDataSym<>
is derived from DynamicData<>
I wonder if there is a way that anytime I create a new derive class from DynamicData<>
I can have is_dynamic<>
work automatically.
the design with the templates cannot be changed, and no virtual methods are allowed, Also working with C++17, so c++20 & C++23 out of the equation!
class ClrngAssetBuff
{
int name1 {};
public:
int GetName();
};
template<typename t1, typename t2, bool a>
struct DynamicData
{
t1 m1;
t2 m2;
};
template<typename t1, typename t2, int sym>
struct DynamicDataSym : DynamicData<t1, t2, true>
{
int some() { return sym; }
};
template<typename t1>
struct DynamicDataSym2 : DynamicData<t1, float, true>
{
float some() { return 1.0f; }
};
template<typename T>
constexpr bool is_dynamic(const T& t)
{
return false;
}
template<typename T1, typename T2, bool a>
constexpr bool is_dynamic(const DynamicData<T1, T2, a>& t)
{
return true;
}
template<typename T1, typename T2, int a>
constexpr bool is_dynamic(const DynamicDataSym<T1, T2, a>& t)
{
return true;
}
template<typename T>
constexpr bool is_dynamic2()
{
return is_dynamic<>(T {});
}
template<typename T> void DoDynamicInfo(const T& t);
template<typename T> void ExecuteMessage(const T& t);
template<typename T>
void ProcessMessage(const T& t)
{
if (is_dynamic2<T>())
DoDynamicInfo(t);
ExecuteMessage(t);
}
int main(int argc, char** argv)
{
ClrngAssetBuff msg1;
ProcessMessage(msg1);
DynamicData<int, double, false> msg2;
ProcessMessage(msg2);
DynamicDataSym<int, int, 10> msg3;
ProcessMessage(msg3);
DynamicDataSym2<long long> msg4;
ProcessMessage(msg4); // oops should call DoDynamicInfo(msg4)
}
If I correctly understand what do you want... you're looking for something as follows
template <typename T1, typename T2, bool B>
std::true_type is_dynamic_helper (DynamicData<T1, T2, B> *);
std::false_type is_dynamic_helper (...);
template <typename T>
constexpr auto is_dynamic
= decltype(is_dynamic_helper(std::declval<T*>()))::value;
that is a template variable (available starting from C++14, so is good for a C++17 solution) that is true
when a pointer of the template T
type can be converted to a DynamicData<T1, T2, B>
(for generics T1
, T2
types and a generic boolean B
value), false
otherwise.
So is_dynamic
is true
when T
is a DynamicData
or derive from a DynamicData
. Unfortunately this doesn't works when T
derive from two or more DynamicData
classes.
Observe that I've made is_dynamic
a constexpr
variable, so you can use is constexpr
, if you want, inside ProcessMessage()
template <typename T>
void ProcessMessage(const T& t)
{
if constexpr ( is_dynamic<T> )
DoDynamicInfo(t);
ExecuteMessage(t);
}
The following is a full compiling C++17 example
#include <iostream>
class ClrngAssetBuff
{
int name1 {};
public:
int GetName();
};
template <typename t1, typename t2, bool a>
struct DynamicData
{ t1 m1; t2 m2; };
template <typename t1, typename t2, int sym>
struct DynamicDataSym : DynamicData<t1, t2, true>
{ int some() { return sym; } };
template <typename t1>
struct DynamicDataSym2 : DynamicData<t1, float, true>
{ float some() { return 1.0f; } };
template <typename T>
void DoDynamicInfo(const T& t)
{ std::cout << "Do Dynamic Info" << std::endl; }
template <typename T>
void ExecuteMessage(const T& t)
{ std::cout << "Execute Message" << std::endl; }
template <typename T1, typename T2, bool B>
std::true_type is_dynamic_helper (DynamicData<T1, T2, B> *);
std::false_type is_dynamic_helper (...);
template <typename T>
constexpr auto is_dynamic
= decltype(is_dynamic_helper(std::declval<T*>()))::value;
template <typename T>
void ProcessMessage(const T& t)
{
if constexpr ( is_dynamic<T> )
DoDynamicInfo(t);
ExecuteMessage(t);
}
int main()
{
ClrngAssetBuff msg1;
std::cout << "---- msg1" << std::endl;
ProcessMessage(msg1);
DynamicData<int, double, false> msg2;
std::cout << "---- msg2" << std::endl;
ProcessMessage(msg2);
DynamicDataSym<int, int, 10> msg3;
std::cout << "---- msg3" << std::endl;
ProcessMessage(msg3);
DynamicDataSym2<long long> msg4;
std::cout << "---- msg4" << std::endl;
ProcessMessage(msg4); // now call DoDynamicInfo(msg4)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.