簡體   English   中英

如何基於模板推導進行 static 調度

[英]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 T1T2類型和通用的 boolean B值),否則為false

因此,當TDynamicData或派生自DynamicData時, is_dynamictrue 不幸的是,當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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM