当前位置: 首页 > 知识库问答 >
问题:

标准::is_convertible与标准不一致::功能

杨轶
2023-03-14

我注意到当涉及到std::function对象和std::bind时,std::is_convertible和std::is_assignable会产生一些奇怪的结果。

我假设当这些函数返回true时,就可以进行转换了。还是我错过了什么?

下面的代码在不同的编译器上打印不同的结果,我希望它打印0,因为这些类型不能赋值。

#include <type_traits> 
#include <functional> 
#include <iostream> 

int main()
{
    std::cout << std::is_convertible<std::function<void(int)>, std::function<void()>>::value << std::endl;
}

它在以下编译器上打印0:

    null

它在以下编译器上打印 1:

  • 4.7
  • VC 12 (VS2013)
  • 叮当声 3.2

有没有正确的答案?这些错误是在编译器中,还是我正在弄乱编译器特定的东西?

共有1个答案

颜修为
2023-03-14

在 C 11 中,std::函数的构造函数采用任意函子类型被指定为 (引用 N3337 §20.8.11.2.1 [函数包装.func.con]/p7):

template<class F> function(F f);
template <class F, class A> function(allocator_arg_t, const A& a, F f);

7 要求:F 应为可复制的对于参数类型 ArgTypes 和返回类型 R,f 应为可调用 (20.8.11.2)。A 的复制构造函数和析构函数不得引发异常。

违反 Requires 子句(为参数类型 ArgTypes 传递 f 不可调用和返回类型 R)是未定义的行为,因此在这种情况下,库可以自由地执行任何操作。该库可能会将构造函数从重载分辨率中移除,但它不必这样做,如果没有,那么您将遇到重载解析和std::is_convertible的问题 - 它将报告太阳下的几乎所有内容都可以转换为std::function(包括像double这样的东西!

因此,在 LWG 问题 2132 中,标准被修改为要求如果函子对于指定的参数类型和返回类型不可调用,则实现从重载解析中删除这些构造函数(通过 SFINAE 或类似技术)。它现在显示为:

template<class F> function(F f);
template <class F, class A> function(allocator_arg_t, const A& a, F f);

7 要求:F 应为可复制的

8 备注:这些构造函数不得参与重载解析,除非对于参数类型 ArgTypes... 和返回类型 Rf可调用的 (20.9.11.2)。

所以如果你的标准库实现了这个解析,那么< code>std::is_convertible

我假设当这些函数返回true时,就可以进行转换了。还是我错过了什么?

诸如< code>std::is_convertible、< code > STD::is _ constructible 或< code>std::is_assignable之类的类型特征只考虑直接上下文,即是否存在可访问且未删除的匹配函数签名。它们不检查函数体在实例化时是否会编译。

 类似资料:
  • 我对标准差的计算有点执着,如果你能在下面的两个问题上给我一些帮助,那就太好了。 代码 问题1:我如何计算这个的标准误差(平均值的标准偏差)? 代码 问题2:如何计算累积标准偏差? 非常感谢!!(很抱歉数据格式错误!)

  • Python 标准库(Python Standrad Library)中包含了大量有用的模块,同时也是每个标准的 Python 安装包中的一部分。熟悉 Python 标准库十分重要,因为只要你熟知这些库可以做到什么事,许多问题都能够轻易解决。 我们将探索这个库中的一些常用模块。你能在你的 Python 安装包中附带的文档中的“库概览(Library Reference)” 部分中查找到所有模块的全

  • String string.byte string.char string.dump string.find string.format string.gmatch string.gsub string.len string.lower string.match string.rep string.reverse string.sub string.upper 在st

  • Object 对象 属性描述对象 Array 对象 包装对象 Boolean 对象 Number 对象 String 对象 Math 对象 Date 对象 RegExp 对象 JSON 对象

  • POSIX(Portable Operating System Interface for Computing Systems)是由IEEE 和ISO/IEC 开发的一簇标准。该标准是基于现有的UNIX 实践和经验,描述了操作系统的调用服务接口,用于保证编制的应用程序可以在源代码一级上在多种操作系统上移植运行。它是在1980 年早期一个UNIX 用户组(usr/group)的早期工作的基础上取得的

  • Werkzeug 的设计意图是一个实用的工具集而不是一个框架。得益于从低级API 中分离出来 的面向用户友好的 API,Werkzeug 可以很简单的扩展另一个系统。 Request 和 Response 对象(又名”wrappers”) 提供的函数也可以来实 现一个小的功能。 例子 这个例子实现一个小的 Hello World 应用。显示用户输入的名字: from werkzeug.utils