我有以下 C++ 程序:
#include <iostream>
#include <functional>
template<class T> void fun(T t) {
if (t) std::cout << t();
else std::cout << "no t";
}
int main() {
std::function<int ()> f;
fun(f); //The check will evaluate to false
fun([](){return "hello";});
int x = 2;
fun([x](){return x;}); // Compiler error
return 0;
}
但是它无法编译。问题似乎是捕获某些内容的 lambda 被转换为仿函数对象,而仿函数对象又不能转换为 bool
,因此无法检查其真实性。
如何正确编写 fun
才能让 main
保持原样?有没有办法在保持事情简单的同时做到这一点(即不专门化fun
)?
编辑:我真的只关心检查 t
是否为真,并且我很高兴假设 T
是可调用的类型,而不明确检查。
最佳答案
您将需要进行某种专门化或重载,但您至少可以将工作分离到谓词函数中:
template<class T>
typename std::enable_if<
std::is_constructible<bool, T>::value, bool>::type
okToCall(T&&t) { return static_cast<bool>(t); }
template<class T>
constexpr typename std::enable_if<
!std::is_constructible<bool, T>::value, bool>::type
okToCall(T&&) { return true; }
template<class T> void fun(T t) {
if (okToCall(t)) std::cout << t();
else std::cout << "no t";
}
示例:http://coliru.stacked-crooked.com/a/a08468965ed6d54e
唯一真正的困难是弄清楚如何调用 okToCall
谓词函数 - 它真正做的是如果 T
是 T
则返回 true
em>不能转换为bool
,但如果它可转换,则其值会转换为bool
。
关于c++ - 检查模板参数是否为 "true"可调用对象的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34682892/