std ::函数与可呼叫作为模板参数

发布于 2025-02-02 23:37:08 字数 1549 浏览 3 评论 0原文

在下面的示例中,为什么第20行会导致第27行到30行描述的错误?

在第33行中调用exec1正常工作。

#include <cstdint>
#include <functional>
#include <iostream>
#include <tuple>
#include <type_traits>

template <typename... t_fields>
void exec0(std::function<std::tuple<t_fields...>()> generate,
           std::function<void(t_fields &&...)> handle) {
  std::tuple<t_fields...> _tuple{generate()};
  std::apply(handle, std::move(_tuple));
}

template <typename t_generate, typename t_function>
void exec1(t_generate generate, t_function handle) {
  auto _tuple{generate()};
  std::apply(handle, std::move(_tuple));
}

int main() {
  auto _h = [](uint32_t u) -> void { std::cout << "u = " << u << '\n'; };

  auto _g = []() -> std::tuple<uint32_t> { return std::tuple<uint32_t>{456}; };

  //  exec0<uint32_t>(_g, _h);
  /*
main.cpp:25:3: error: no matching function for call to 'exec0'
main.cpp:8:6: note: candidate template ignored: could not match
'function<tuple<unsigned int, type-parameter-0-0...> ()>' against '(lambda at
/var/tmp/untitled002/main.cpp:23:13)'
  */

  exec1(_g, _h);

  return 0;
}

g ++ - version回复:

g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

In the example below, why line 20 causes the error described from line 27 to 30?

Calling exec1 in line 33 works fine.

#include <cstdint>
#include <functional>
#include <iostream>
#include <tuple>
#include <type_traits>

template <typename... t_fields>
void exec0(std::function<std::tuple<t_fields...>()> generate,
           std::function<void(t_fields &&...)> handle) {
  std::tuple<t_fields...> _tuple{generate()};
  std::apply(handle, std::move(_tuple));
}

template <typename t_generate, typename t_function>
void exec1(t_generate generate, t_function handle) {
  auto _tuple{generate()};
  std::apply(handle, std::move(_tuple));
}

int main() {
  auto _h = [](uint32_t u) -> void { std::cout << "u = " << u << '\n'; };

  auto _g = []() -> std::tuple<uint32_t> { return std::tuple<uint32_t>{456}; };

  //  exec0<uint32_t>(_g, _h);
  /*
main.cpp:25:3: error: no matching function for call to 'exec0'
main.cpp:8:6: note: candidate template ignored: could not match
'function<tuple<unsigned int, type-parameter-0-0...> ()>' against '(lambda at
/var/tmp/untitled002/main.cpp:23:13)'
  */

  exec1(_g, _h);

  return 0;
}

g++ --version replies:

g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

桃酥萝莉 2025-02-09 23:37:08

即使您指定&lt; uint32_t&gt;作为模板参数,编译器似乎试图推断出参数包的更多元素,但未能这样做(因为lambda的类型不是> > std :: function&lt; ...&gt;),变得不高兴。

您需要以某种方式抑制模板参数扣除。

将其称为exec0&lt; uint32_t&gt;({_ g},{_h});,或在std :: type_identity_t&lt; ...&gt;(OR)中包装参数类型,pre-c ++ 20,std :: enable_if_t&lt; true,...&gt;)。

然后,编译器将接受您的uint32_t作为包装中的唯一类型,并且不会尝试添加更多类型。

Even though you specified <uint32_t> as a template argument, the compiler seems to try to deduce more elements for the parameter pack, fails to do so (because the type of a lambda is not std::function<...>), and becomes upset.

You need to somehow inhibit template argument deduction.

Either call it as exec0<uint32_t>({_g}, {_h});, or wrap parameter types in std::type_identity_t<...> (or, pre-C++20, std::enable_if_t<true, ...>).

Then the compiler will accept your uint32_t as the only type in the pack, and won't try to add more types.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文