簡體   English   中英

具有相同名稱但參數類型不同的多個函數作為模板參數

[英]multiple functions with same name but different argument types as template parameter

我正在使用xsd從xml架構文件創建c ++代碼。 對於xml類型,創建了多個函數(用於序列化等)。
如果類型被稱為XmlType ,則創建以下形式的多個函數:

XmlType XmlType_(const XmlType& a, const string& b)
string XmlType_(const XmlType& a)
...

這是普通函數,而不是XmlType的成員,它們都具有相同的名稱。 對於XmlType2 ,函數將被稱為XmlType2_

我想為我的xml方案的所有不同xml類型編寫一個實用程序模板類。 不同的功能將在本課程中被稱為洞察力。 到目前為止我所擁有的是這樣的:

template<typename T>
using TFunc1 = T (*)(const T&, const string&);
template<typename T>
using TFunc2 = string (*)(const T&);

template<typename T, TFunc1<T> func2, TFunc2<T> func2>
class XmlUtil {
... 
}; 

當創建XmlUtil類的實例時,如果必須這樣做:

XmlUtil<XmlType, XmlType_, XmlType_> util; 

當我必須傳遞更多函數作為參數時,這感覺有點多余並且變得更糟。

我想像這樣使用util類:

XmlUtil<XmlType, XmlType_> util; 

或者甚至更好

XmlUtil<XmlType> util; 

我能想到的唯一方法是以某種方式使用define,但感覺不對。
還有其他辦法嗎?

編輯:我現在正在使用一個定義:

#define TRPL(name) name, name ## _, name ## _
...
XmlUtil<TRPL(XmlType)> util;

我會編輯這個,如果我找到更好的東西(也許像Yakk在他的回答中建議的覆蓋集)。

這個:

XmlUtil<XmlType> util;

是不可能的,因為沒有辦法從XmlTypeXmlType_ 在自動代碼生成器之后,它們的關系被丟棄。

不過這個:

XmlUtil<XmlType_> util;

可能是可能的。 您可以推導出XmlType_的函數類型,然后使用推導的返回類型,它將是XmlType 我相信有這個目的的標准庫函數。

至於兩個不同的重載,這可能比較棘手。 我不認為你可以將函數重載集作為模板參數傳遞,解析是在模板參數的上下文中的模板參數上完成一個函數。 我不認為有一種方法可以在不使用預處理器的情況下推遲此操作。

所以我認為你應該使用#define 總比沒有好。

這看起來像是覆蓋集的作業。

static struct foo_override_set_type {
  template<typename... Args>
  auto operator()( Args...&& args ) const
  ->
    decltype( foo( std::forward<Args>(args)... ) )
  {  return ( foo( std::forward<Args>(args)... ) ); }
  template<typename T>
  operator T() { return foo; }
} foo_override_set;

foo_override_set_type類型的foo_override_set_type表示foo的整個覆蓋集。 使用operator()調用它們會在foo上執行覆蓋集查找並調用生成的函數。 將它們轉換為函數指針與將標記foo轉換為函數指針(或其他值)的方法相同。

您的代碼生成可以自動生成此類覆蓋集類型。 它還可以創建一個traits類,它通過特化從您的XmlType類型XmlTypeXmlType_函數的覆蓋集。

然后,你XmlUtil<XmlType>可以訪問覆寫集的XmlType_通過該特性類。 它首先實例化覆蓋集變量,然后對其進行invokes ()

順便說一句,@ Xeo有一個建議, []XmlType_在C ++ 1y或C ++ 1z中輸入[]XmlType_一樣簡單地創建這樣的對象。

類定義中的默認模板參數?

喜歡

template<typename T, TFunc1<T> func1 = XmlType_, TFunc2<T> func2 = XmlType_>
class XmlUtil {
    // ...
};

你可以使用這樣的特質類

template <typename T>
struct Trait{
    typedef T type;
    typedef T (*func1)(const T&, const string&);
    typedef string (*func2)(const T&);
};

並使類XmlUtil有一個模板參數(讓我們將其命名為Trait)並使用Trait :: type,Trait :: func1和Trait :: func2。 請參閱此處以了解完整用法

在示例中,XmlUtil的類型如下:

XmlUtil<Trait<XmlType> >

我這樣做了,因為我不太了解你的問題。 可能是您可以直接將Trait類定義到XmlUtil並使用

 XmlUtil<XmlType>

其他變化是可能的,它取決於您的需求。

您可以在此處閱讀有關特質課程的簡短介紹。 如果你想了解更多關於這個主題的信息,我建議你使用Modern C ++(Alexandrescu)。

我不確定我完全明白你在問什么。 序列化和反序列化的常用方法是創建工廠(抽象工廠)並動態解析對象的構造。 請注意,這可以針對復雜結構進行改進,其中代碼生成器可以創建成員函數以提取每個成員的確切類型。

但同樣,我並不完全明白你真正要做的事情......作為一項建議,我相信如果你提供更多關於問題的描述可以解決問題,因為問題集中在如何制定你的解決方案工作,並隱含地丟棄可能更好的設計的其他方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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