gpt4 book ai didi

c++ - std::is_convertible 与 std::function 不一致

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:34:33 32 4
gpt4 key购买 nike

当涉及 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:

  • gcc 4.8 和 gcc 4.9
  • clang 3.4(但不是来自 ubuntu 12.04 的那个)

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

  • 海湾合作委员会 4.7
  • VC++12 (VS2013)
  • clang 3.2

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

最佳答案

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

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

7 Requires: F shall be CopyConstructible. f shall be Callable (20.8.11.2) for argument types ArgTypes and return type R. The copy constructor and destructor of A shall not throw exceptions.

违反 Requires 子句(传递 f 而不是 Callable 参数类型 ArgTypes 和返回类型 R )是未定义的行为,因此库可以自由地做任何事情在那种情况下它想要。该库可能会将构造函数从重载决议中移除,但它不是必须的,如果不是,那么你将遇到重载决议和 std::is_convertible 的问题。 - 它将报告几乎所有在阳光下的东西都可以转换为 std::function (包括 double 之类的东西!)。

因此,在 LWG issue 2132 , 如果仿函数不是 Callable,标准被修改为要求实现从重载解析中删除这些构造函数(通过 SFINAE 或类似技术)对于指定的参数类型和返回类型。现在是:

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

7 Requires: F shall be CopyConstructible.

8 Remarks: These constructors shall not participate in overload resolution unless f is Callable (20.9.11.2) for argument types ArgTypes... and return type R.

所以如果你的标准库实现了这个解析,那么std::is_convertible<std::function<void(int)>, std::function<void()>>::valuefalse .否则,它取决于实现。

I would assume that when these functions return true, the conversion can be made. Or am I missing something?

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

关于c++ - std::is_convertible 与 std::function 不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25879865/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com