c++26新功能—带原因说明的删除函数
一、C++对函数的隐藏/删除处理
在早期的C++开发中,为了一些实际的需要,可能会对一些函数隐藏,比如在某些情况下需要禁止构造函数或拷贝构造函数等,那么就将其移动到私有函数中处理即可。这样对外的接口便被禁止了。而到了C++11标准后,标准库提供了=delete的形式,来显式的阻止编译器生成此函数。这样做的好处不言而喻,但这样做也会有一些副作用,比如大量的引入=delete,设计者可能就会忘记最初的目的是为什么要删除这个函数。而后面代码的应用者和维护者也会产生相同的问题。所以在C++26中提供了一个带删除说明的=delete。
二、C++26中的删除函数
在最新的提案中,删除函数的基本的形式如下:
= delete("reason");
大家都知道,在C++26标准前,要想实现一种带有说明内容的控制代码,常见的有以下几种情况:
1、使用类似断言static_assert(expr, “reason”)等来处理(C++11)
2、使用属性[[deprecated(“with reason”)]],但它不会阻止编译(C++14)
3、使用属性[[nodiscard(“with reason”)]],同样也会阻止编译(C++17)
怎么说呢?它们都比较好用,但终究在应用到=delete时感到有些不爽。
三、应用例程
看一下不同标准下相关的例程比较:
//C++98
class NonCopyable
{
public:// ...NonCopyable() {}
private:// copy members; no definitionNonCopyable(const NonCopyable&);NonCopyable& operator=(const NonCopyable&);
};
//C++11
class NonCopyable
{
public:// ...NonCopyable() = default;// copy membersNonCopyable(const NonCopyable&) = delete;NonCopyable& operator=(const NonCopyable&) = delete;// maybe provide move members instead
};
//C++26
class NonCopyable
{
public:// ...NonCopyable() = default;// copy membersNonCopyable(const NonCopyable&)= delete("Since this class manages unique resources, \
copy is not supported; use move instead.");NonCopyable& operator=(const NonCopyable&)= delete("Since this class manages unique resources, \
copy is not supported; use move instead.");// provide move members instead
};
代码一对比非常清晰,怎么着更容易为开发者所接受是非常容易理解的。
四、=delete限制的场景
虽然说这个删除形式非常好用,但在实际应用时也有场景限制的,如下:
1、纯虚拟函数不允许使用,虚函数的删除要严格处理
2、不能删除override标记的函数(类似于1)
3、对某些函数不建议或者严格限制使用,比如删除析构函数、构造函数等
4、不能删除某些模板中的实例化函数
5、注意不能应用到非函数的场景,比如变量就不可以应用
##五、总结
本文介绍的其实是一个把边边沿沿的小功能组合一下,让其更加容易使用并达到相关的应用目的的库的完善。没有什么高大上的功能,但就如好车上一些小细节的处理,让开发者感到舒适和方便,这其实也体现了标准的强大之处。