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

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

std::invoke of a function template/lambda fails

问题

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

#include <bits/stdc++.h> // to include everything

int main() {
    const auto func = [&](typename T)(const std::string& h) {
        T t;
        std::cout << t << " " << h << "\n";
    };
    std::invoke(func<std::string>, std::string("Hello"));
}

Error: 

<source>:17:33: error: expected primary-expression before '>' token
   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.

#include &lt;bits/stdc++.h&gt; // to include everything

int main() {
    const auto func = [&amp;]&lt;typename T&gt;(const std::string&amp; h) {
        T t;
        std::cout &lt;&lt; t &lt;&lt; &quot; &quot; &lt;&lt; h &lt;&lt; &quot;\n&quot;;
    };
    std::invoke(func&lt;std::string&gt;, std::string(&quot;Hello&quot;));
}

Error:

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

答案1

得分: 2

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

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

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

或更"简单"地:

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

演示

英文:

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

As T is not deducible, you might write:

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

or more "simply":

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

Demo

答案2

得分: 0

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

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

#include <string>
#include <iostream>
#include <functional>

template <typename T>
void func(const std::string& h)
{
    T t;
    std::cout << t << " " << h << "\n";
}

int main() 
{
    std::invoke(func<std::string>, std::string("Hello"));
}

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:

#include &lt;string&gt;
#include &lt;iostream&gt;
#include &lt;functional&gt;

template &lt;typename T&gt;
void func(const std::string&amp; h)
{
    T t;
    std::cout &lt;&lt; t &lt;&lt; &quot; &quot; &lt;&lt; h &lt;&lt; &quot;\n&quot;;
}

int main() 
{
    std::invoke(func&lt;std::string&gt;, std::string(&quot;Hello&quot;));
}

Live demo - Godbolt

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

答案3

得分: 0

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

#include "bits/stdc++.h"

int main() {
    const auto f = []<typename T>(std::string) -> void {};
    std::invoke(&decltype(f)::operator()<int>, f, "hello");
}
英文:

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)

#include &quot;bits/stdc++.h&quot;

int main() {
    const auto f = []&lt;typename T&gt;(std::string) -&gt; void {};
    std::invoke(&amp;decltype(f)::operator()&lt;int&gt;, f, &quot;hello&quot;);
}

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:

确定