检查模板参数是否为"true"可调用对象的正确方法是什么?
What is the correct way to check whether a template argument is a "true" callable object?
我有以下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
。
相关文章:
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 是什么让放置新调用对象的构造函数?
- 这个C++编译器优化(在自身的实例上调用对象自己的构造函数)的名称是什么,它是如何工作的?
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 具有相同特征的两个对象是否只在内存中存储一次?无论定义它们的函数是什么,都是不同的
- 为对象分配整数.输出将是什么?
- 在C++中,创建'n'数量的对象的推荐方法是什么,其中n是用户定义的。我该怎么做?
- 使用 gtest 框架在单元测试代码中检查目标对象的私有变量的最佳实践是什么?
- 处理从列表中删除指向对象的指针的"healthy"方法是什么?
- 在C++中返回 IO 对象的目的是什么?
- 在C++中有多个指向单个对象的指针的正确方法是什么?
- 初始化对象以在 C++08 中作为参数传递的首选语法是什么?
- 将(临时的?)std::string传递给使用它来构造一个接受副本的对象的函数的最佳方法是什么?
- C++:允许临时对象调用非常量成员函数的设计理念是什么?
- 使用对函数和IO对象的引用(作为参数)的目的是什么
- 在多个对象中初始化预定义成员变量的正确方法是什么?
- 在 c++ 中重置大型对象实例的最佳方法是什么
- 将对象传递给模板构造函数或方法的正确方法是什么
- C 中的对象依赖性.什么是班级组成的语法
- "没有满足这些约束的较小数组对象"是什么意思?