lambda 转换为布尔值,而不是推导函数指针类型
lambda converted to bool instead of deducing function-pointer-type
我想为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 ptrn" << 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
,并接受模板 vararg 列表。
即使非捕获 lambda 具有到函数指针的隐式转换,函数模板也必须完全匹配才能成功进行演绎,不会执行任何转换。
因此,最简单的解决方法是使用+
强制转换
int main() {
std::boolalpha(std::cout);
std::cout << []{return 5;} << std::endl; // true is outputted
test(+[]{return 5;});
// ^
}
template<typename T>
void test(bool) {
std::cout << "bool" << std::endl;
}
不需要模板。事实上,重载函数,而不是模板。将其替换为
void test(bool) {
std::cout << "bool" << std::endl;
}
现在,您的示例将编译。
相关文章:
- QMetaObject invokeMethod的基于函数指针的语法
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- c++r值引用应用于函数指针
- 模板函数指针和lambda
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 带有类的函数指针
- () 函子后面的括号,而不是函数指针?
- 全局作用域中函数指针的赋值
- 使用"Task"函数指针队列定义作业管理器
- 将成员函数指针作为参数传递给模板方法
- 如何创建对象函数指针C++映射?
- 匹配函数指针作为模板参数?
- 通过函数指针定义类范围之外的方法
- 存储在类中的函数指针
- C++从函数指针数组调用函数
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 整数键映射到头文件中的成员函数指针
- 从类成员函数到类 C 函数指针的转换
- 如何将内联匿名函数分配给C++函数指针
- 将字符缓冲区强制转换为函数指针