我有以下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
是一个可调用的类型,而没有明确检查
答案 0 :(得分:2)
您需要进行某种专业化或重载,但您至少可以将工作分离为谓词函数:
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
谓词函数的内容 - 如果true
不1>,它正在做的是返回T
em>可转换为bool
,但如果 可转换,则其值转换为bool
。