std::is_callable 有什么问题?

问题描述 投票:0回答:1

自 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
。为什么?

c++ c++17 language-lawyer type-traits
1个回答
0
投票

std::is_callable 的 Fn(Args...) 方法有什么问题?

这可以从P0604第3项中得到回答,其中指出:

替换 is_callable 和 result_of 中类型列表的函数类型编码:

这些类型特征中使用的函数类型编码形式是 C++ 前可变参数模板时代的遗留物,其中单个类型用于表达类型列表。 首先,对于这两个特征,编码形式Fn(ArgTypes...)

的自然解释看起来就像
Fn
用作返回类型,但它只是提供参数的可调用对象。 
第二,与使用基于泛左值的表达式方法的其他类型特征相反,由于直接使用 declval 应用于给定的类型参数,函数类型编码对于非泛左值更自然。特别是,参数类型首先通过特殊的类似衰减的机制(8.3.5 [dcl.fct])进行调整,使得实际提供的类型通常不是实际测试所应用的类型。另一个问题是函数返回类型和参数类型阻止了一些重要的类型类以编码形式实际提供:参数类型既不能有抽象类类型也不能有 cv void 类型,函数类型或数组类型也不能用作“返回”类型”。

© www.soinside.com 2019 - 2024. All rights reserved.