簡體   English   中英

std::invoke_result 在具有自動返回類型的模板函數中不起作用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM