C++26 中的 `std::function` 是否已被 `std::copyable_function` 弃用?

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

C++26 提供

std::copyable_function
[cppref 链接]。然而,现有的
std::function
已经是
copyable
了。所以,我有3个问题:

  1. std::copyable_function
    相对于
    std::function
    的主要优势是什么?

  2. 调用空的

    std::copyable_function
    是未定义的,而调用空的
    std::function
    会抛出异常。背后的原理是什么?

  3. C++26 中

    std::function
    是否已被
    std::copyable_function
    弃用?

c++ function c++11 standards c++26
1个回答
0
投票

std::copyable_function
相对于
std::function
的主要优势是什么?

有两个。

首先,没有

target()
API,反正它通常也不是超级有用,因此开销较少,因为
std::copyable_function
不必跟踪
std::function
所做的事情。但这是次要的。

更重要的是API接口。

std::function
看起来像这样:

struct function<R(Args...)> {
    R operator()(Args...) const;
};

呼叫操作员 (1) 总是

const
并且 (2) 从不
noexcept
。 (1) 是一个问题,因为您仍然可以在无意中调用非
const
成员函数。

std::copyable_function
看起来像这样:

struct copyable_function<R(Args...) cv ref noexc> {
  R operator()(Args...) cv ref noexc;
};

这意味着,例如,

copyable_function<void(int)>
有一个非
const
、非
noexcept
调用操作符,但
copyable_function<void(int) const noexcept>
有一个既是
const
又是
noexcept
的操作符。所有这些都是具体的。

这使得用法更清晰、更正确。

调用空的 std::copyable_function 是未定义的,而调用空的 std::function 将抛出异常。背后的原理是什么?

可以说,调用空的

std::function
是一个错误。有很多人认为抛出信号程序员错误是一种不好的方法 - 称其为未定义行为意味着实现可以断言。

C++26 中的

std::function
是否已被
std::copyable_function
弃用?

这个问题的字面答案是:不。但也许更有趣的问题是:本来应该如此吗?我仍然会回答“不”。

有大量代码使用

std::function
,其中很大一部分可能是正确的。这也不是一个简单的重命名过渡,因为许多用途都希望从
function<R(Args...)>
更改为
copyable_function<R(Args...) const>
。但也有许多用途希望改为
move_only_function<R(Args...) const>

实际进行这些更改可能是个好主意(特别是如果您不需要

target()
,而......没有人需要)。但它们并没有那么紧迫,以至于你实际上想要一个
[[deprecated]]
警告。看起来更像是一种低调、铿锵、整洁的现代化暗示的建议。

这里实际上有两个层次:

  1. A
    不好(可能有害),
    B
    非常优越,请切换。
  2. A
    还可以,
    B
    更好。在新代码中更喜欢
    B
    ,但
    A
    无害。

auto_ptr<T>
过渡到
unique_ptr<T>
适合第一类。从
function<R(Args..)>
过渡到
copyable_function<R(Args...) const>
(或
move_only_function<R(Args...) const>
,有时甚至是
function_ref<R(Args...) const>
)对我来说更像是第二类。
A
还好。不要因为我仍在旧代码中使用它而对我大喊大叫。

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