删除的构造函数"accessible"吗?

Are deleted constructors "accessible"?

本文关键字:accessible 删除 构造函数      更新时间:2023-10-16

关于已删除的移动构造函数的问题的已删除答案引用cppreference.com的话说,只要移动构造函数是"可访问的",即使它不是"可用的",is_move_constructible特性也应该成功。

事实上,该标准要求论点类型的移动结构形成良好,因此答案并不完全正确。

现在,该标准反复使用"可访问"一词来表示实际的可构建性。例如:

[C++11 8.5/6]:默认初始化类型为T的对象意味着:

  • 如果T是(可能是cv限定的)类类型(第9条),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化形式不正确)
  • 如果T是数组类型,则每个元素都默认初始化
  • 否则,不执行初始化

如果程序调用常量限定类型T的对象的默认初始化,则T应为具有用户提供的默认构造函数的类类型。

然而,我在标准中找不到明确说明deleted显式定义的构造函数是否"可访问"的地方。

一个不同的[非规范性的]引用似乎表明deleted-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­可建构性特征。这与使用de­let函数导致程序格式错误。

从问题中的第二句话中,我想说可访问性不受deleted的影响,并且第一句话实际上根本不包括这样的构造函数可能是deleted的情况。

相反,delete:的定义中包含了一种"包罗万象"的需求

[C++11: 8.4.3/2]:隐式或显式引用已删除函数而不是声明该函数的程序是格式错误的[注意:这包括隐式或显式调用函数,并形成指向函数成员的指针或指针。它甚至适用于未潜在求值的表达式中的引用。如果函数重载,则只有在通过重载解析选择函数时才会引用它。--结束注释]

因此,cppreference.com可能需要注意,除了移动构造函数是否可访问之外,还有另一个标准适用于is_move_constructible特性。这里还有一个进一步的问题,即MoveConstructible也可以由CopyConstructible满足,所以即使是move构造函数本身也不是严格必要的。

然而,这一切提出了另一个有趣的观点,即is_move_constructible的任何可能的实现都必须"引用"已删除的move构造函数,这会导致程序格式不正确,正如上面引用的那样。尽管如此,我认为有了SFINAE技巧,实现可以避免实际变得不规范。


"一个完全没有移动构造函数但有复制构造函数的类型是可移动构造的(可从右值构造)。"—DyP