删除所有构造函数(或其他函数)的最佳样式? [英] Best style for deleting all constructors (or other function)?
问题描述
假设我要创建一个无法构造的类型(不要问为什么).
struct Impossible
{
我可以这样:
Impossible() = delete;
// disable automatically generated constructors, don't declare any others
Impossible(const Impossible&) = delete;
// I suppose this is redundant with nothing to copy
或类似这样:
Impossible(...) = delete;
// explicitly disable all constructors
或类似这样:
template<typename... Ts>
Impossible(Ts...) = delete;
// explicitly disable all constructors, template version
};
我想我可以对任何函数问同样的事情,而不仅仅是构造函数.
我选择哪一个有什么不同?在语法方面,我想我喜欢第二种选择.但是,在任何情况下,是否有可能检测到差异(错误消息中的文字除外)?
有区别,例如:
#include <type_traits>
struct Unconstructible
{
Unconstructible() = delete;
};
static_assert( !std::is_default_constructible<Unconstructible>::value, "not default constructible" );
static_assert( std::is_copy_constructible<Unconstructible>::value, "copyable" );
尽管您永远无法构造该对象,所以在实践中您也永远无法根据库中的语言和类型特征创建一个对象的副本,但从技术上讲,它是CopyConstructible的,因为存在一个隐式声明的副本构造函数. /p>
类似地,使用Impossible(...)
或Impossible(Ts&&...)
形式,仍然存在一个隐式声明的副本构造函数.
另一方面,如果您这样做:
#include <type_traits>
struct Unconstructible
{
Unconstructible(const Unconstructible&) = delete;
};
static_assert( !std::is_default_constructible<Unconstructible>::value, "not default constructible" );
static_assert( !std::is_copy_constructible<Unconstructible>::value, "not copyable" );
用户声明的构造函数的存在抑制了默认构造函数的隐式声明,因此该类既不是DefaultConstructible也不是CopyConstructible.
您的最后一个示例应该是Impossible(Ts&&...)
,以匹配任何类型,包括不可复制和不可移动的类型.
Let's say I want to make a type that cannot be constructed (don't ask why).
struct Impossible
{
I could do it like this:
Impossible() = delete;
// disable automatically generated constructors, don't declare any others
Impossible(const Impossible&) = delete;
// I suppose this is redundant with nothing to copy
or like this:
Impossible(...) = delete;
// explicitly disable all constructors
or like this:
template<typename... Ts>
Impossible(Ts...) = delete;
// explicitly disable all constructors, template version
};
I guess I could ask the same thing about any function, not just constructors.
Does it make any difference which one I choose? In terms of syntax I think I like the second option. But is there any situation, whatsoever, where it's possible to detect a difference (other than in the text of an error message)?
There is a difference, for example:
#include <type_traits>
struct Unconstructible
{
Unconstructible() = delete;
};
static_assert( !std::is_default_constructible<Unconstructible>::value, "not default constructible" );
static_assert( std::is_copy_constructible<Unconstructible>::value, "copyable" );
Although you can never construct this object, so in practice you can never create a copy of one either, according the language and the type traits in the library, it is technically CopyConstructible, because there's an implicitly-declared copy constructor.
Similarly, with the Impossible(...)
or Impossible(Ts&&...)
forms there is still an implicitly-declared copy constructor.
On the other hand, if you do it this way:
#include <type_traits>
struct Unconstructible
{
Unconstructible(const Unconstructible&) = delete;
};
static_assert( !std::is_default_constructible<Unconstructible>::value, "not default constructible" );
static_assert( !std::is_copy_constructible<Unconstructible>::value, "not copyable" );
The existence of a user-declared constructor suppresses the implicit declaration of the default constructor, so the class is neither DefaultConstructible nor CopyConstructible.
N.B. your last example should probably be Impossible(Ts&&...)
to match any types, including non-copyable and non-movable ones.
这篇关于删除所有构造函数(或其他函数)的最佳样式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!