
1. C++ Handling of Function Hiding/Deletion
In early C++ development, for practical reasons, some functions might be hidden. For example, in certain cases, it may be necessary to prohibit constructors or copy constructors, which can be handled by moving them to private functions. This effectively disables the external interface. However, with the C++11 standard, the standard library introduced the =delete syntax to explicitly prevent the compiler from generating these functions. The benefits of this approach are obvious, but it also has some side effects. For instance, with the extensive use of =delete, designers might forget the original reason for deleting a function. Similarly, users and maintainers of the code may face the same issue. Therefore, C++26 introduces a =delete with a reason explanation.
2. Delete Function in C++26
In the latest proposal, the basic form of the delete function is as follows:
= delete("reason");
As we all know, prior to the C++26 standard, to implement a control code with explanatory content, there were several common approaches:1. Using assertions like static_assert(expr, “reason”) (C++11)2. Using attributes [[deprecated(“with reason”)]], but this does not prevent compilation (C++14)3. Using attributes [[nodiscard(“with reason”)]], which also prevents compilation (C++17)These methods are quite useful, but ultimately feel somewhat unsatisfactory when applied to =delete.
3. Application Examples
Let’s look at a comparison of related examples under different standards:
//C++98
class NonCopyable
{
public:
// ...
NonCopyable() {}
private:
// copy members; no definition
NonCopyable(const NonCopyable&);
NonCopyable& operator=(const NonCopyable&);
};
//C++11
class NonCopyable
{
public:
// ...
NonCopyable() = default;
// copy members
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
// maybe provide move members instead
};
//C++26
class NonCopyable
{
public:
// ...
NonCopyable() = default;
// copy members
NonCopyable(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
};
The comparison of the code is very clear, making it easier for developers to understand and accept.
4. Limitations of =delete
Although this delete form is very useful, there are limitations in practical applications, as follows:1. Pure virtual functions are not allowed to use this; deletion of virtual functions must be handled strictly.2. Functions marked with override cannot be deleted (similar to 1).3. Certain functions are not recommended or strictly limited for deletion, such as destructors and constructors.4. Cannot delete certain instantiated functions in templates.5. Note that it cannot be applied to non-function scenarios, such as variables.
5. Conclusion
This article introduces a small feature that combines various elements to make it easier to use and achieve relevant application goals. There is nothing particularly grand about it, but like the handling of small details in a good car, it provides comfort and convenience for developers, which reflects the power of the standard.