Reputation: 26836
I have the following C++ program:
#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;
}
But it doesn't compile. The problem seems to be that a lambda that captures something is converted to a functor object, which in turn is not convertible to bool
and therefore cannot be checked for truthfulness.
What's the right way of writing fun
so that I can leave main
as it is? Is there a way of doing this while keeping things simple (i.e. not specializing fun
)?
EDIT: I really only care about checking whether t
is true or not, and I am happy to assume that T
is a callable type, without checking that explicitly.
Upvotes: 2
Views: 141
Reputation: 157344
You're going to need to do some kind of specialization or overloading, but you can at least separate out the work into a predicate function:
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";
}
Example: http://coliru.stacked-crooked.com/a/a08468965ed6d54e
The only real difficulty is working out what to call the okToCall
predicate function - what it's really doing is returning true
if T
is not convertible to bool
, but its value converted to bool
if it is convertible.
Upvotes: 2