![](/img/trans.png)
[英]Why is it illegal for non-templated functions to have same name and arguments but different return types? (but legal for template functions?)
[英]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;
是不可能的,因為沒有辦法從XmlType
到XmlType_
。 在自動代碼生成器之后,它們的關系被丟棄。
不過這個:
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
類型XmlType
到XmlType_
函數的覆蓋集。
然后,你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.