函数模板/lambda 的 std::invoke 失败

std::invoke of a function template/lambda fails

提问人:Happytreat 提问时间:6/29/2023 最后编辑:wohlstadHappytreat 更新时间:9/2/2023 访问量:130

问:

我怎样才能让它工作?(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"));
}

错误:

<source>:17:33: error: expected primary-expression before '>' token
   17 |     std::invoke(func<std::string>, std::string("Hello"));
C++ 函数 模板 lambda

评论

0赞 463035818_is_not_an_ai 6/29/2023
请不要从代码中删除包含。需要它们来重现您的错误。如果没有包含此代码,则会产生完全不同的错误。你要求其他人努力编译不必要的代码
0赞 Happytreat 6/29/2023
我已经包含了所有内容 - 使用标头本身(这只是一个在 godbolt 中失败的虚拟示例,但它足以复制我在 prod 中面临的问题)
1赞 463035818_is_not_an_ai 6/29/2023
为什么我不应该 #include < bits/stdc++.h>
1赞 Eljay 6/29/2023
#include <bits/stdc++.h>私有编译器头文件。不要自己包括它。
2赞 463035818_is_not_an_ai 6/29/2023
func不是模板。它有一个模板化的operator()

答:

2赞 Jarod42 6/29/2023 #1

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

由于无法推导,您可以这样写:T

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

或更“简单”:

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

演示

0赞 wohlstad 6/29/2023 #2

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

使用 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"));
}

现场演示 - Godbolt

旁注:最好避免 #include < bits/stdc++.h>

0赞 weineng 6/30/2023 #3

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

#include "bits/stdc++.h"

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

评论