請考慮以下例子:
template<auto const fnc>
struct dummy_s {
typedef std::invoke_result<decltype(fnc), std::uint8_t >:type return_t;
};
int main() {
dummy_s<[](std:: uint8_t const& n) -> bool { return true ^ n; }> : :return_t s = true;
}
是否有辦法在不指定std::uint8_t或任何引數數量的情況下獲得回傳型別,作為模板引數的例子。
uj5u.com熱心網友回復:
你可以寫一個元函式,給你第一個引數的型別
template<typename Ret, typename Arg>
auto arg(Ret(*)(Arg)) -> Arg。
然后將lambda fnc衰減到一個函式指標(使用 說),你將其傳遞給arg,然后在typedef中使用它。
typedef std::invoke_result<decltype(fnc)。
decltype(arg( fnc))>:type return_t;
這只適用于不捕獲任何東西的lambdas,并且只接受一個引數。
你也可以通過直接使用
arg來大大簡化結構內部的型別定義,就像這樣
using return_t = decltype(arg( fnc))。 //使用比typedef還要干凈。
這就完全避免了使用invoke_result,并讓你以一種允許將多個引數的lambdas傳遞給它的方式定義arg
template< typename Ret, typename Arg, typename. ...R>。
auto arg(Ret(*)(Arg, R...)) -> Arg;
這里有一個demo
uj5u.com熱心網友回復:
正如我在評論中所說,每次我認為我需要這個功能的時候,我都會在后來發現我走錯了路。原因是,只要lambda是一個模板(auto),就沒有希望使它作業。
更廣泛地說,如果你沒有一個函式的 "宇宙 "輸入的線索,從概念上來說,你就沒有一個真正的函式。
如果你認為你仍然需要它,你可以使用Boost.TypeTraits,lambda decay和函式指標。
#include<cstdint>
#include<boost/type_traits.hpp>/span>
int main(){
auto f = [](std:: uint8_t const& n) -> bool {return true ^ n; };
using f_return = boost::function_traits<decltype(* f)>:result_type。
static_assert( std::is_same<f_return, bool>{} , "!)
}
對于f的任何泛化,多載或模板,都不會作業。
你真的很幸運,因為語言中的一系列怪癖,從單態函式的存在開始(從C中繼承,指標衰減,等等),這類作業。從概念上講,這是很可怕的。
盡管如此,還有一個潛在的問題對你所使用的C 版本非常敏感,那就是在模板(非評估)背景關系中使用lambdas。
這是基于你的代碼的作業解決方案。 在某些編譯器和標志的組合下,它確實可以正常作業,例如https://godbolt.org/z/5x684nfWc :
#include<cstdint>
#include<boost/type_traits.hpp>/span>
template<auto fnc>
struct dummy_s {
using return_t = typename boost::function_traits<decltype(* fnc)> :result_type。
};
int main() {
typename dummy_s< [](std:: uint8_t const& n) -> bool { return true ^ n; }> 。 :return_t s = true;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/316132.html
標籤:
下一篇:如何防止C 中的模板型別擴展?
