2012-12-04 38 views
19

(我將這個問題限制在C++ 11中,因爲我相信在C++ 98中沒有這樣做的一般方法)。在C++中重命名(別名/轉發)函數的最佳方式是什麼?

假設我有一個複雜的(在簽名計算)設置模板功能和/或重載函數,我想以完全相同的方式來使用這些功能,但使用不同的名稱(即別名)。

例如:

template<class A, class B, class C> 
D fun(A a, B& b, C&& c){ ... } 

template<class E, class F> 
G fun(H<E> he, F& f){ ... } 

... many other versions of fun 

現在假設我想重命名(或別名,或更精確)這些功能,都在一次(即能夠使用同一個功能的不同名稱,而不用重寫它)。這樣,在代碼的其他部分,我可以使用不同的名稱並且不需要修改上面的代碼。

這是正確的方式重命名(別名/轉發)fun轉換成gun

template<typename... Args> 
inline auto gun(Args&&... args)->decltype(fun(std::forward<Args>(args)...)){ 
    return fun(std::forward<Args>(args)...); 
} 
  • 難道真的有什麼看法?
  • 這是最簡單的方法嗎?
  • 這是最佳方式嗎? (例如可以內聯,沒有不必要的副本)
  • 如果原始函數具有一些SFINAE功能,該怎麼辦? (例如template<class A, class B, class C, class = std::enable_if<...>::type>),decltype會在所有情況下轉移SFINAE嗎?
  • 如果原始函數返回引用該怎麼辦?是不是decltype去除引用類型? (例如double& fun(double& x){return x;})。
  • 關於成員函數可以這麼說嗎?

澄清:gun永遠不會是正好fun,因爲實例將有不同的地址,但我在找的是對的觀點通用編碼的點的重命名。我發現奇怪的是,幾乎所有的東西都可以被重命名/轉發,命名空間,類型(typedef)和模板類型using typedef,但不是函數(或關於成員函數)。


編輯:爲了完整,而且由於這似乎是這樣做的方式,在這裏我添加了一個宏來定義函數別名:

#define ALIAS_FUNCTION(OriginalnamE, AliasnamE) \ 
template <typename... Args> \ 
inline auto AliasnamE(Args&&... args) -> decltype(OriginalnamE(std::forward<Args>(args)...)) { \ 
    return OriginalnamE(std::forward<Args>(args)...); \ 
} 

,然後你使用它像這樣:

namespace NS1{namepsace NS2{ 
    ALIAS_FUNCTION(NSA::fun, gun); // second argument (target name can't have namespace) 
}} 
+2

我認爲這很好。 'decltype'獲得正確的類型(即'&'用於返回左值引用的函數,'&&'用於返回右值引用的函數,否則爲非引用)。 –

+7

拜託,如果你描述你實際在做什麼,你會讓每個人都變得更加輕鬆。你不重命名*任何*。原來的名字仍然存在。您正在轉發,或提供別名或包裝函數。這與重命名沒有任何關係。重命名意味着*更改*名稱,使舊名稱消失,轉而使用新名稱 – jalf

+0

@jalf,好點。我想,讓原來的名字消失很難。我想象的唯一方法是將原始定義放入一個未命名的名稱空間中。但是,是的,這不是主意。 – alfC

回答

10

難道真的有什麼看法?

是的。

這是最簡單的方法嗎?

是的(遺憾的是)。

這是最佳方式嗎? (例如可以內聯,沒有不必要的副本)

是的。

如果原始函數具有一些SFINAE功能會怎麼樣? (例如template<class A, class B, class C, class = std::enable_if<...>::type>),在所有情況下都會decltype轉移SFINAE?

是的,如果內部decltype表達產生錯誤(即,fun不存在,這可能是由於SFINAE上fun),這將觸發SFINAE爲gun藏漢,從過載集合移除它。

如果原始函數返回引用會怎樣?是不是decltype去除引用類型? (例如double& fun(double& x){return x;})。

不,爲什麼呢?

對於成員函數可以這麼說,儘管這樣做必須修改我猜的類。

這不是問題。關於會員功能可以說些什麼?以上所有內容同樣適用。

+1

+1爲「可悲」。由於我沒有收到否定答案,我會將其標記爲已接受。 – alfC

相關問題