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

标签 c++ templates lambda

我有以下 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 谓词函数 - 它真正做的是如果 TT 则返回 true em>不能转换为bool,但如果它可转换,则其值会转换为bool

关于c++ - 检查模板参数是否为 "true"可调用对象的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34682892/

相关文章:

c++ - 声明对象

c++ - 编译器可以告诉我它选择了哪个重载函数或模板函数吗?

c++ - 使用 CRTP 强制显式模板实例化

c++ - 如何在 C++11 中将 lambda 表达式存储为类的字段?

c# - SelectMany 三层深

c++ - 对临时对象的常量引用

c++ - boost::program_options 的链接错误

c++ - 全局键盘 Hook 不起作用

python - Django URL、模板、模型和 View 的命名约定

c++ - 从引用类型在 lambda 中捕获的值的类型,不使用广义捕获