c++ - lambda 转换为 bool 而不是推导函数指针类型

标签 c++ lambda function-pointers ostream template-argument-deduction

我想为 operator<< 实现重载这让我可以调用给定的函数并输出结果。 因此我写了一个重载,但是选择了到 bool 的转换,当我自己写一个函数时,它不会编译。

编辑:知道我不想调用 lambda, 而是将它传递给应该使用默认构造的参数列表调用它的函数。

我已经附加了我的代码:

#include <iostream>

template<typename T>
void test(T *) {
    std::cout << "ptr" << std::endl;
}
template<typename T>
void test(bool) {
    std::cout << "bool" << std::endl;
}
template<typename Ret, typename ...Args>
void test(Ret(*el)(Args...)) {
    std::cout << "function ptr\n" << el(Args()...) << std::endl;
}

template<typename Char_T, typename Char_Traits, typename Ret, typename ...Args>
std::basic_ostream<Char_T, Char_Traits>& operator<<(
      std::basic_ostream<Char_T, Char_Traits> &str, Ret(*el)(Args...)) {
    return str << el(Args()...);
}

int main() {
    std::boolalpha(std::cout);
    std::cout << []{return 5;} << std::endl; // true is outputted
    test([]{return 5;}); // will not compile
}

我使用带有版本标志的 gcc 7.3.1 -std=c++14 .

编辑:错误信息:

main.cc: In function ‘int main()’:
main.cc:25:23: error: no matching function for call to ‘test(main()::<lambda()>)’
     test([]{return 5;});
                       ^
main.cc:5:6: note: candidate: template<class T> void test(T*)
 void test(T *) {
      ^~~~
main.cc:5:6: note:   template argument deduction/substitution failed:
main.cc:25:23: note:   mismatched types ‘T*’ and ‘main()::<lambda()>’
     test([]{return 5;});
                       ^
main.cc:9:6: note: candidate: template<class T> void test(bool)
 void test(bool) {
      ^~~~
main.cc:9:6: note:   template argument deduction/substitution failed:
main.cc:25:23: note:   couldn't deduce template parameter ‘T’
     test([]{return 5;});
                       ^
main.cc:13:6: note: candidate: template<class Ret, class ... Args> void test(Ret (*)(Args ...))
 void test(Ret(*el)(Args...)) {
      ^~~~
main.cc:13:6: note:   template argument deduction/substitution failed:
main.cc:25:23: note:   mismatched types ‘Ret (*)(Args ...)’ and ‘main()::<lambda()>’
     test([]{return 5;});

最佳答案

您的问题是模板参数推导在传递给test 的实际参数上完成.并不是对参数可能转换成的所有可能类型都这样做。这可能是一个无限集,所以这显然是不行的。

所以,模板参数推导是在实际的 lambda 对象上完成的,它有一个不可描述的类类型。所以扣除test(T*)失败,因为 lambda 对象不是指针。 T不能从 test(bool) 推导出来, 明显地。最后,推导失败test(Ret(*el)(Args...))因为 lambda 对象也不是指向函数的指针。

有几个选项。您甚至可能不需要模板,您可以接受 std::function<void(void)>并依赖于它具有模板化构造函数这一事实。或者你可以拿 test(T t)参数并将其命名为 t() . T现在将推导出实际的 lambda 类型。最奇特的解决方案可能是使用 std::invoke ,并接受模板可变参数列表。

关于c++ - lambda 转换为 bool 而不是推导函数指针类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49284932/

相关文章:

c - 访问结构体中定义的函数指针?

c++ - 模板类中的模板可变参数函数无法编译

c++ - 在自定义命名空间下包含 header ?

c# - 如何将多个 MethodCallExpressions 加入一个 Expression?

c++ - C++ lambda 真的会复制通过复制捕获的参数吗?

c# - 如何使用 linq 从 1 行数据构建对象?

c++ - 函数指针赋值在 C 中有效,但在 C++ 中无效

c++ - 为什么删除 const 和非常量方法中的代码重复不是未定义的行为?

c++ - 打印出一个 std::vector<std::wstring>

c++ - popen()如何工作以及如何在Linux上将其实现为C++代码?