关于已删除的移动构造函数的this question上的已删除答案引用cppreference.com as saying,只要移动构造函数是“可访问的”,is_move_constructible
特征就应该成功,即使它不是“可用的” ”
标准实际上要求参数类型的移动构造是格式良好的,所以答案并不完全正确。
现在,该标准重复使用与构造函数相关的术语“可访问”,指的是实际的可构造性。例如:
[C++11 8.5/6]:
要默认初始化,T
类型的对象意味着:
- 如果
,则格式错误T
是(可能是 cv-qualified )类类型(第9条),则调用T
的默认构造函数(初始化为如果T
没有可访问的默认构造函数);- 如果
T
是数组类型,则每个元素都是默认初始化;- 否则,不执行初始化。
如果程序要求对const限定类型
T
的对象进行默认初始化,则T
应为具有用户提供的默认构造函数的类类型。
但是,我无法在标准中的任何地方找到明确说明delete
d,显式定义的构造函数是否“可访问”。
一个不同的[非规范]引用似乎表明delete
d-ness和可访问性是正交的:
[C++11: 12.2/1]:
[..] [注意:即使没有调用析构函数或复制/移动构造函数,所有语义限制,例如可访问性(第11条)和是否删除功能(8.4.3)。 [..]
答案 0 :(得分:12)
我不想解决cppreference网站所说的内容,但就标准而言,可构造性并未根据“可访问的构造函数”进行定义。相反,主要定义是is_constructible
的定义,即(C ++ 11,20.9.4.3/6):
is_constructible<T, Args...>
应满意 当且仅当以下变量定义适用于某些发明变量
时t
:T t(create<Args>()...);
执行访问检查,就像在与
T
和任何Args
无关的上下文中一样。只考虑变量初始化的直接上下文的有效性。
因此,最后一行代码中假设表达的良构性是构造性特征的定义特征。这与使用删除函数导致格式错误的程序的条款密切配合。
答案 1 :(得分:9)
从问题的第二个引用开始,我说可访问性不受delete
dness的影响,并且第一个引用实际上不 涵盖了这样的构造函数可能是delete
d。
此方案由delete
的定义中的某种“包罗万象”要求涵盖:
[C++11: 8.4.3/2]:
隐式或显式地引用已删除函数的程序,除了声明它之外,都是格式错误的。 [注意:这包括隐式或显式调用函数并形成指向函数的指针或指向成员的指针。它甚至适用于未进行潜在评估的表达式中的引用。如果函数重载,则仅在通过重载决策选择函数时才引用它。 -end note]
因此,cppreference.com可能会注意到还有一个适用于is_move_constructible
特征的标准,而不仅仅是移动构造函数是否可访问。这里还有一个问题,那就是CopyConstructible
也可以满足is_move_constructible
†,所以即使是移动构造函数本身也不是绝对必要的。
这一切都提出了另一个有趣的观点,即{{1}}的任何可能实现都必须“引用”已删除的移动构造函数,这会导致程序格式错误,如上面引用中所述。尽管如此,我认为使用SFINAE技巧可以避免实际上变形。
†“一个没有移动ctor的类型,但有一个复制器是可移动构造的(可从rvalue构造)。” - MoveConstructible