std::invoke调用函数模板/lambda失败

huangapple go评论120阅读模式
英文:

std::invoke of a function template/lambda fails

问题

How can I get this working? (C++17/20)
注意:我必须在这里使用 std::invoke,因为在实际代码中,我唯一的保证是这个可调用对象是可以调用的。

  1. #include <bits/stdc++.h> // to include everything
  2. int main() {
  3. const auto func = [&](typename T)(const std::string& h) {
  4. T t;
  5. std::cout << t << " " << h << "\n";
  6. };
  7. std::invoke(func<std::string>, std::string("Hello"));
  8. }
  9. Error:
  10. <source>:17:33: error: expected primary-expression before '>' token
  11. 17 | std::invoke(func<std::string>, std::string("Hello"));
英文:

How can I get this working? (C++17/20)
Note: I have to use std::invoke here because in the real code, the only guarantee I have is that this callable is invokable.

  1. #include &lt;bits/stdc++.h&gt; // to include everything
  2. int main() {
  3. const auto func = [&amp;]&lt;typename T&gt;(const std::string&amp; h) {
  4. T t;
  5. std::cout &lt;&lt; t &lt;&lt; &quot; &quot; &lt;&lt; h &lt;&lt; &quot;\n&quot;;
  6. };
  7. std::invoke(func&lt;std::string&gt;, std::string(&quot;Hello&quot;));
  8. }

Error:

  1. &lt;source&gt;:17:33: error: expected primary-expression before &#39;&gt;&#39; token
  2. 17 | std::invoke(func&lt;std::string&gt;, std::string(&quot;Hello&quot;));

答案1

得分: 2

lambda不是模板,但它的operator()是。

由于T无法推断出来,你可以这样写:

  1. std::invoke([&](const std::string &s) { func.operator()<std::string>(s); },
  2. std::string("Hello"));

或更"简单"地:

  1. func.operator()<std::string>("Hello");

演示

英文:

lambda is not template, but its operator() is.

As T is not deducible, you might write:

  1. std::invoke([&amp;](const std::string &amp;s) { func.operator()&lt;std::string&gt;(s); },
  2. std::string(&quot;Hello&quot;));

or more "simply":

  1. func.operator()&lt;std::string&gt;(&quot;Hello&quot;);

Demo

答案2

得分: 0

问题在于您的lambda函数func不是一个函数模板,而是具有模板化的operator()

使用您尝试的方式使用std::invoke的一种方法是实际上将func更改为函数模板

  1. #include <string>
  2. #include <iostream>
  3. #include <functional>
  4. template <typename T>
  5. void func(const std::string& h)
  6. {
  7. T t;
  8. std::cout << t << " " << h << "\n";
  9. }
  10. int main()
  11. {
  12. std::invoke(func<std::string>, std::string("Hello"));
  13. }

Live demo - Godbolt

一点额外说明: 最好避免使用#include <bits/stdc++.h>

英文:

The problem is that your lambda func is not a function template, but rather has a templated operator().

One way to use std::invoke the way you attempted, would be to actually change func into a function template:

  1. #include &lt;string&gt;
  2. #include &lt;iostream&gt;
  3. #include &lt;functional&gt;
  4. template &lt;typename T&gt;
  5. void func(const std::string&amp; h)
  6. {
  7. T t;
  8. std::cout &lt;&lt; t &lt;&lt; &quot; &quot; &lt;&lt; h &lt;&lt; &quot;\n&quot;;
  9. }
  10. int main()
  11. {
  12. std::invoke(func&lt;std::string&gt;, std::string(&quot;Hello&quot;));
  13. }

Live demo - Godbolt

A side note: better to avoid #include <bits/stdc++.h>.

答案3

得分: 0

一种方法是传递指向成员函数的指针(&decltype(f)::operator()<int>),然后给它传递对象(f)和参数(std::string

  1. #include "bits/stdc++.h"
  2. int main() {
  3. const auto f = []<typename T>(std::string) -> void {};
  4. std::invoke(&decltype(f)::operator()<int>, f, "hello");
  5. }
英文:

One way is to pass the pointer-to-member function (&amp;decltype(f)::operator()&lt;int&gt;), then give it the object (f) and the arguments(std::string)

  1. #include &quot;bits/stdc++.h&quot;
  2. int main() {
  3. const auto f = []&lt;typename T&gt;(std::string) -&gt; void {};
  4. std::invoke(&amp;decltype(f)::operator()&lt;int&gt;, f, &quot;hello&quot;);
  5. }

huangapple
  • 本文由 发表于 2023年6月29日 19:30:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76580616.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定