C++26 提供
std::copyable_function
[cppref 链接]。然而,现有的std::function
已经是copyable
了。所以,我有3个问题:
std::copyable_function
相对于std::function
的主要优势是什么?
调用空的
std::copyable_function
是未定义的,而调用空的std::function
会抛出异常。背后的原理是什么?
C++26 中
std::function
是否已被 std::copyable_function
弃用?
相对于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]]
警告。看起来更像是一种低调、铿锵、整洁的现代化暗示的建议。
这里实际上有两个层次:
A
不好(可能有害),B
非常优越,请切换。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
还好。不要因为我仍在旧代码中使用它而对我大喊大叫。