[英]std::invoke_result doesn't work in a template function with auto return type
我正在嘗試使用std::invoke_result_t
並且在具有auto
返回類型的函數中調用嵌套 lambda 時失敗。 這是一個復制器:
template <typename T, typename... Args>
auto print_ret_type(T &&t, Args &&... args) {
using ret_type = std::invoke_result_t<T, Args...>;
std::cout << typeid(ret_type).name() << std::endl;
}
int main(int argc, const char **argv) {
auto worker = [](int i) {
auto worker_impl = [](int i, auto &worker) {
print_ret_type(worker, i, worker);
};
worker_impl(i, worker_impl);
};
worker(10);
return 0;
}
我收到以下錯誤:
include/c++/9.3.0/type_traits:2783:5: error: no type named 'type' in 'std::invoke_result<(lambda at test.cpp:13:24) &, int &, (lambda at test.cpp:13:24) &>'
using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
如果我對print_ret_type
使用void
返回類型而不是auto
則測試編譯成功。 我的原始代碼中有一個返回的模板結構,它取決於ret_type
。 誰能解釋為什么在使用auto
返回類型時會出現錯誤?
返回類型推導如何工作的規則有點古怪。
為了確定返回類型,它實際上實例化了函數體。 此實例化中的任何錯誤都是硬錯誤。
Lambda 的返回類型是隱式的->auto
基本上是->auto
; 所以這些規則適用於他們。 如果您想知道worker
的返回類型,則必須實例化worker
每一行, worker_impl
。
auto worker = [](int i) {
auto worker_impl = [](int i, auto &worker) {
print_ret_type(worker, i, worker);
};
worker_impl(i, worker_impl); // << worker_impl has no return type yet
};
worker(10);
要求返回類型:
template <typename T, typename... Args>
auto print_ret_type(T &&t, Args &&... args) {
using ret_type = std::invoke_result_t<T, Args...>;
此函數在worker_impl
內部實例化以確定其返回類型,以確定worker_impl
的返回類型。
將其更改為將->void
添加到worker_impl
:
auto worker_impl = [](int i, auto &worker)->void {
它編譯,或print_ret_type
返回void
。
在我們還不知道worker_impl
的返回類型的時候,任何一個都會阻止調用結果的實例化。
天真地,簡單的規則“無return
語句, auto
返回體返回void
”將是您認為使用的規則。 但是 C++ 沒有這個規則。
返回類型推導並不能解決所有可能的情況。 有時您必須明確返回類型。
推導返回類型時發生的事情的規則並不像他們想象的那么狹窄。 雖然print_ret_type
的返回類型與print_ret_type
的返回類型worker_impl
,但標准(出於對編譯器實現者的慷慨)讓他們在那里做一些更接近“真正編譯”的事情。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.