自 2017 年 3 月 13 日起,
std::is_callable
已从 cppreference.com 消失。最后可用的描述是 2016 年 11 月 21 日在 WaybackMachine.
std::is_callable
和取代它的std::is_invocable
之间的主要区别是
template <class FnArgs>
专门用于 FnArgs
= Fn(Args...)
可调用类型 Fn
和要测试的参数类型 (Args...
),而 template <class Fn, class... Args>
)。std::is_callable
的Fn(Args...)
方法有什么问题吗?
我明白,
Fn(Args...)
是一个函数类型,其中Fn
是返回类型。 std::is_callable
给了 Fn
另一个含义,即要测试的函数类型,我认为这具有误导性。这只是一个问题。你能说出其余所有的名字吗?
我能想到的,但不能把它们放在一起(用关键词):
void
,抽象类,C 数组,函数类型,可恶的函数类型,不完整的类型浮现在脑海中。const
,函数、数组和引用类型的衰减可能会发挥作用(参见LWG2895)。Fn(Args...)
方法在某些情况下可能会带来歧义。如果您展示如何让
std::is_callable
在 Godbolt 上工作,您将获得“奖金”。我尝试过一些使用C++17的编译器,但都说命名空间中没有这种类型std
。为什么?
std::is_callable 的 Fn(Args...) 方法有什么问题?
这可以从P0604第3项中得到回答,其中指出:
替换 is_callable 和 result_of 中类型列表的函数类型编码:
这些类型特征中使用的函数类型编码形式是 C++ 前可变参数模板时代的遗留物,其中单个类型用于表达类型列表。 首先,对于这两个特征,编码形式
Fn(ArgTypes...)
的自然解释看起来就像Fn
用作返回类型,但它只是提供参数的可调用对象。第二,与使用基于泛左值的表达式方法的其他类型特征相反,由于直接使用 declval 应用于给定的类型参数,函数类型编码对于非泛左值更自然。特别是,参数类型首先通过特殊的类似衰减的机制(8.3.5 [dcl.fct])进行调整,使得实际提供的类型通常不是实际测试所应用的类型。另一个问题是函数返回类型和参数类型阻止了一些重要的类型类以编码形式实际提供:参数类型既不能有抽象类类型也不能有 cv void 类型,函数类型或数组类型也不能用作“返回”类型”。