[英]How to do static dispatch base on derivation on a template
如果對象屬於某些模板/類,我如何專門化模板 function 以返回 true,而對於其他模板/類則返回 false 沒有類具有虛函數。 我有一個模板:
template<typename t1, typename t2, bool a> struct DynamicData{...}
我想做特殊處理,或從該模板派生的任何 class。 在下面的示例中,我對DynamicData<>
進行了專門化: DynamicDataSym<>
,為此我對is_dynamic<>
進行了專門化,但是因為DynamicDataSym<>
是從DynamicData<>
派生的,所以我想知道是否有一種方法可以隨時創建一個new derive class from DynamicData<>
我可以讓is_dynamic<>
自動工作。
使用模板的設計無法更改,並且不允許使用虛方法,還可以使用 C++17,因此 C++20 和 C++23 不在等式中!
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)
}
如果我正確理解你想要什么......你正在尋找如下內容
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;
這是一個模板變量(從 C++14 開始可用,因此適用於 C++17 解決方案)當模板T
類型的指針可以轉換為DynamicData<T1, T2, B>
時為true
(對於 generics T1
, T2
類型和通用的 boolean B
值),否則為false
。
因此,當T
是DynamicData
或派生自DynamicData
時, is_dynamic
為true
。 不幸的是,當T
從兩個或多個DynamicData
類派生時,這不起作用。
請注意,我已將is_dynamic
constexpr
變量,因此您可以根據需要在ProcessMessage()
中使用is constexpr
template <typename T>
void ProcessMessage(const T& t)
{
if constexpr ( is_dynamic<T> )
DoDynamicInfo(t);
ExecuteMessage(t);
}
下面是完整編譯C++17的例子
#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)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.