检查模板参数是否为"true"可调用对象的正确方法是什么?

What is the correct way to check whether a template argument is a "true" callable object?

本文关键字:对象 是什么 方法 调用 参数 是否 true 检查      更新时间:2023-10-16

我有以下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)?

EDIT:我真的只关心检查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不可转换为bool,它真正要做的是返回true,但如果它可转换的,它的值转换为bool

相关文章: