C++ 17轉(zhuǎn)發(fā)一個函數(shù)調(diào)用的完美實現(xiàn)
前言
本文主要給大家介紹了關(guān)于C++17轉(zhuǎn)發(fā)一個函數(shù)調(diào)用的相關(guān)內(nèi)容,分享出來供大家參考學(xué)習(xí),下面話不多說了,來一起看看詳細(xì)的介紹吧。
方法如下
首先你靈光一閃:
#define WARP_CALL(fun, ...) fun(__VA_ARGS__)
不我們并不喜歡宏,擴展性太差了
template<class R, class T1, class T2, class T3>
R warp_call(R(*fun)(T1, T2, T3), T1 a, T2 b, T3 c)
{
return fun(a, b, c);
}
如果你寫出來上面這段代碼,你肯定是從C轉(zhuǎn)過來的,C++還沒用熟??紤]callable object和C++11 variadic template特性用上:
template<class Fun, class... Args>
auto wrap_call(Fun f, Args... args) -> decltype(f(args...))
{
return f(args...);
}
加上移動語義,返回值推導(dǎo):
template<class Fun, class... Args>
auto wrap_call(Fun&& f, Args&&... args)
{
return std::forward<Fun>(f)(std::forward<Args>(args)...);
}
auto返回值實際上會有參數(shù)被decay的問題,用decltype + 尾置返回值
template<class Fun, class... Args>
auto wrap_call(Fun&& f, Args&&... args)
-> decltype(std::forward<Fun>(f)(std::forward<Args>(args)...))
{
return std::forward<Fun>(f)(std::forward<Args>(args)...);
}
有了C++14,可以直接使用decltype(auto)
template<class Fun, class... Args>
decltype(auto) wrap_call(Fun&& f, Args&&... args)
{
return std::forward<Fun>(f)(std::forward<Args>(args)...);
}
別忘了noexcept
template<class Fun, class... Args>
decltype(auto) wrap_call(Fun&& f, Args&&... args)
noexcept(noexcept(std::forward<Fun>(f)(std::forward<Args>(args)...)))
{
return std::forward<Fun>(f)(std::forward<Args>(args)...);
}
但是上面的函數(shù)不是SFINAE-friendly的,因為decltype(auto)返回值的函數(shù)并不能直接從函數(shù)簽名獲得返回值,而對這個函數(shù)進行返回值推導(dǎo),是可能產(chǎn)生hard error打斷SFINAE的。所以最好手動寫返回值
template<class Fun, class... Args>
auto wrap_call(Fun&& f, Args&&... args)
noexcept(noexcept(std::forward<Fun>(f)(std::forward<Args>(args)...)))
-> decltype(std::forward<Fun>(f)(std::forward<Args>(args)...))
{
return std::forward<Fun>(f)(std::forward<Args>(args)...);
}
我們還遺漏了啥?constexpr
template<class Fun, class... Args>
constexpr auto wrap_call(Fun&& f, Args&&... args)
noexcept(noexcept(std::forward<Fun>(f)(std::forward<Args>(args)...)))
-> decltype(std::forward<Fun>(f)(std::forward<Args>(args)...))
{
return std::forward<Fun>(f)(std::forward<Args>(args)...);
}
上面是完美的
完美嗎?去看看std::invoke
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
C++11右值引用和轉(zhuǎn)發(fā)型引用教程詳解
這篇文章主要介紹了C++11右值引用和轉(zhuǎn)發(fā)型引用教程詳解,需要的朋友可以參考下2018-03-03
c++ 虛函數(shù),虛表相關(guān)總結(jié)
這篇文章主要介紹了c++ 虛函數(shù),虛表的的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下2021-03-03
c/c++拷貝構(gòu)造函數(shù)和關(guān)鍵字explicit詳解
這篇文章主要介紹了c/c++拷貝構(gòu)造函數(shù)和關(guān)鍵字explicit的相關(guān)知識,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-08-08
C語言超詳細(xì)講解結(jié)構(gòu)體與聯(lián)合體的使用
結(jié)構(gòu)體和聯(lián)合體用于描述事物的屬性,如一只鳥的信息,可能包括它的品種,體重,顏色,年齡等,接下來大家一起來詳細(xì)看看吧2022-05-05
C++類與對象深入之靜態(tài)成員與友元及內(nèi)部類詳解
朋友們好,這篇播客我們繼續(xù)C++的初階學(xué)習(xí),現(xiàn)在對我們對C++的靜態(tài)成員,友元,內(nèi)部類知識點做出總結(jié),整理出來一篇博客供我們一起復(fù)習(xí)和學(xué)習(xí),如果文章中有理解不當(dāng)?shù)牡胤?還希望朋友們在評論區(qū)指出,我們相互學(xué)習(xí),共同進步2022-06-06

