我遇到了我不理解的型別特征問題,我創建了以下最小示例。為什么第二次呼叫foo不編譯?它給出了錯誤:
from C:/msys64/mingw64/include/c /10.3.0/bits/nested_exception.h:40,
from C:/msys64/mingw64/include/c /10.3.0/exception:148,
from C:/msys64/mingw64/include/c /10.3.0/ios:39,
from C:/msys64/mingw64/include/c /10.3.0/ostream:38,
from C:/msys64/mingw64/include/c /10.3.0/iostream:39,
from invoke_result_test.cpp:1:
C:/msys64/mingw64/include/c /10.3.0/type_traits: In substitution of 'template<class _Fn, class ... _Args> using invoke_result_t = typename std::invoke_result::type [with _Fn = main()::<lambda(bool&)>; _Args = {bool}]':
invoke_result_test.cpp:6:11: required from here
C:/msys64/mingw64/include/c /10.3.0/type_traits:2957:11: error: no type named 'type' in 'struct std::invoke_result<main()::<lambda(bool&)>, bool>'
2957 | using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
閱讀它看起來該函式不可呼叫,因此 invoke_result 沒有type回傳。我希望能夠使用參考呼叫 foo 以便我可以回傳值和非參考,但無法解決這個問題。這可能嗎?我假設是 STL 代碼管理這個。我有什么不明白的?
最小代碼:
#include <type_traits>
template <typename F,
typename... A,
typename R = std::invoke_result_t<std::decay_t<F>, std::decay_t<A>...>>
R foo(const F& aF, const A& ...aA)
{
return aF(aA...);
}
int main()
{
bool positive = true;
std::cout << foo([](bool flag) -> int
{
if (flag) return 1;
return -1;
},
positive);
std::cout << foo([](bool& flag) -> int
{
flag = !flag;
if (flag) return 1;
return -1;
},
positive);
}
謝謝。
uj5u.com熱心網友回復:
該錯誤表明該函式不可使用給定引數呼叫。
std::invoke_result自動添加&&到引數型別,除非它們已經有&. 您的函式不能用bool &&引數呼叫。
即使忽略invoke_result,這也無法作業,因為foo通過常量參考接收引數。
您需要完美轉發此類包裝器:
template <typename F, typename... A>
decltype(auto) foo(F &&f, A &&... a)
{
return std::forward<F>(f)(std::forward<A>(a)...);
}
在這里,回傳型別可以手動指定為std::invoke_result_t<F, A...>.
但是為了保持一致性,您還應該將手動f呼叫替換為std::invoke(以支持呼叫諸如指向成員的指標之類的東西)。
template <typename F, typename... A>
std::invoke_result_t<F, A...> foo(F &&f, A &&... a)
{
return std::invoke(std::forward<F>(f), std::forward<A>(a)...);
}
uj5u.com熱心網友回復:
template <typename F,
typename... A,
typename R = std::invoke_result_t<std::decay_t<F>, std::decay_t<A>...>>
R foo(const F& aF, const A& ...aA)
這詢問是否F可以使用右值呼叫右值A。
你不會嘗試這個。你要嘗試的是:
typename R = std::invoke_result_t<F const&, A const&...>>
如果您進行此更改,則代碼現在無法在第二種情況下正確編譯,即您嘗試使用bool&引數呼叫bool const&引數。
如果你想在第二種情況也作業,你不能拿bool的const&,然后把它傳遞給需要一個拉姆達bool&。
template <typename F,
typename... A,
typename R = std::invoke_result_t<F const&, A&&...>>
R foo(const F& aF, A&& ...aA)
{
return aF(std::forward<A>(aA)...);
}
現在兩個測驗用例都編譯。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/346370.html
