被删除的构造函数是否"可访问"?

Lig*_*ica 16 c++ language-lawyer c++11

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

事实上,标准要求参数类型的移动构造是格式良好的,因此答案并不完全正确.

现在,该标准反复使用与构造函数相关的术语"可访问",指的是实际的可构造性.例如:

[C++11 8.5/6]:默认初始化的类型的对象T是指:

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

如果程序要求对const限定类型的对象进行默认初始化T,T则应为具有用户提供的默认构造函数的类类型.

但是,我无法在标准中的任何地方找到明确说明deleted,显式定义的构造函数是否"可访问".

一个不同的[非规范]引用似乎表明deleted-ness和可访问性是正交的:

[C++11: 12.2/1]: [..] [注意:即使没有对析构函数或复制/移动构造函数的调用,也应满足所有语义限制,例如可访问性(第11条)以及函数是否被删除(8.4.3).[..]

  • 我错过了一段吗?
  • 如果没有,是否应更正cppreference.com页面?你能建议更好的措辞吗?
  • 这个标准应该更清楚吗?

Ker*_* SB 12

我不想解决cppreference网站所说的内容,但就标准而言,可构造性不是根据"可访问的构造函数"来定义的.相反,主要定义是,is_constructible(C++ 11,20.9.4.3/6):

is_constructible<T, Args...>
Run Code Online (Sandbox Code Playgroud)

当且仅当以下变量定义适用于某些发明变量时,才应满足t:

T t(create<Args>()...);
Run Code Online (Sandbox Code Playgroud)

执行访问检查就好像在与其无关的上下文T中执行Args.仅考虑变量初始化的直接上下文的有效性.

因此,最后一行代码中假设表达的良构性是构造性特征的定义特征.这与使用删除函数导致程序格式错误的条款密切配合.


Lig*_*ica 9

从讨论的第二个报价,我会说,无障碍不受deletedness,并且第一次报价其实并不在所有覆盖,这样的构造可能的情况下delete天.

相反,这种情况在定义中包含了一种"包罗万象"的要求delete:

[C++11: 8.4.3/2]:除了声明它之外,隐式或显式引用已删除函数的程序是不正确的.[注意:这包括隐式或显式调用函数并形成指向函数的指针或指向成员的指针.它甚至适用于未进行潜在评估的表达式中的引用.如果函数重载,则仅在通过重载决策选择函数时才引用它. - 尾注]

因此,cppreference.com可能会注意到还有一个适用于is_move_constructible特征的标准,而不仅仅是移动构造函数是否可访问.这里还有另外一个问题,这是MoveConstructible可以被满足CopyConstructible,因此,即使在自己的移动构造函数是不是绝对必要的.

然而,这一切都提出了另一个有趣的观点,即任何可能的实现都is_move_constructible必须"引用"已删除的移动构造函数,这会导致程序格式错误,如上面的引用中所述.尽管如此,我认为通过SFINAE技巧,一个实现可以避免实际上变得格格不入.


"一个没有移动ctor的类型,但是有一个复制程序是可移动构造的(可以从rvalue构造)." - DyP

  • 我修复了[MoveConstructible](http://en.cppreference.com/w/cpp/concept/MoveConstructible)以及cppreference上的一些相关内容,以便更多地匹配std.更好? (3认同)