删除的构造函数"accessible"吗?
Are deleted constructors "accessible"?
关于已删除的移动构造函数的问题的已删除答案引用cppreference.com的话说,只要移动构造函数是"可访问的",即使它不是"可用的",is_move_constructible
特性也应该成功。
事实上,该标准要求论点类型的移动结构形成良好,因此答案并不完全正确。
现在,该标准反复使用"可访问"一词来表示实际的可构建性。例如:
[C++11 8.5/6]:
默认初始化类型为T
的对象意味着:
- 如果
T
是(可能是cv限定的)类类型(第9条),则调用T
的默认构造函数(如果T
没有可访问的默认构造函数,则初始化形式不正确)- 如果
T
是数组类型,则每个元素都默认初始化- 否则,不执行初始化
如果程序调用常量限定类型
T
的对象的默认初始化,则T
应为具有用户提供的默认构造函数的类类型。
然而,我在标准中找不到明确说明delete
d显式定义的构造函数是否"可访问"的地方。
一个不同的[非规范性的]引用似乎表明delete
d-ness和可及性是正交的:
[C++11: 12.2/1]:
[..][注:即使没有调用析构函数或复制/移动构造函数,也应满足所有语义限制,如可访问性(第11条)和是否删除函数(8.4.3)
- 我错过了一段吗
- 如果没有,是否应该更正cppreference.com页面?你能建议一个更好的措辞吗
- 无论哪种方式,标准都应该更清楚吗
我不想提及cppreference网站所说的内容,但就标准而言,可构建性并不是用"可访问的构造函数"来定义的。相反,主要的定义是is_constructible
,即(C++11,20.9.4.3/6):
is_constructible<T, Args...>
应满足当且仅当以下变量定义对于某些发明的变量
t
是良好的:T t(create<Args>()...);
如同在与CCD_ 15和CCD_。只考虑变量初始化的直接上下文的有效性。
因此,代码最后一行的假设表达式的良好形式是定义字符ter可建构性特征。这与使用delet函数导致程序格式错误。
从问题中的第二句话中,我想说可访问性不受delete
d的影响,并且第一句话实际上根本不包括这样的构造函数可能是delete
d的情况。
相反,delete
:的定义中包含了一种"包罗万象"的需求
[C++11: 8.4.3/2]:
隐式或显式引用已删除函数而不是声明该函数的程序是格式错误的[注意:这包括隐式或显式调用函数,并形成指向函数成员的指针或指针。它甚至适用于未潜在求值的表达式中的引用。如果函数重载,则只有在通过重载解析选择函数时才会引用它。--结束注释]
因此,cppreference.com可能需要注意,除了移动构造函数是否可访问之外,还有另一个标准适用于is_move_constructible
特性。这里还有一个进一步的问题,即MoveConstructible
也可以由CopyConstructible
满足†,所以即使是move构造函数本身也不是严格必要的。
然而,这一切提出了另一个有趣的观点,即is_move_constructible
的任何可能的实现都必须"引用"已删除的move构造函数,这会导致程序格式不正确,正如上面引用的那样。尽管如此,我认为有了SFINAE技巧,实现可以避免实际变得不规范。
†"一个完全没有移动构造函数但有复制构造函数的类型是可移动构造的(可从右值构造)。"—DyP
- 将数组的地址分配给变量并删除
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C/C++编译器通常会删除重复的库吗
- 从链接列表c++中删除一个项目
- C++如何通过用户输入删除列表元素
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 使用函数"remove"删除重复元素
- 如何从多映射中删除特定的重复项
- 运算符C++ "delete []"仅删除 2 个前值
- 删除指向指针的指针是运行时错误吗
- 将指针设置为"nullptr"并不能防止双重删除?
- 为什么示例代码访问IUnknown中已删除的内存
- 如何通过 getter 函数删除矢量的元素?
- 从控制台中删除最后打印的元素
- C++中的线程安全删除
- 如何从存储在std::映射中的std::集中删除元素
- 删除的构造函数"accessible"吗?