C++ 是否删除了构造函数;“无障碍”吗;?
关于删除的移动构造函数的一个删除的回答引用了C++ 是否删除了构造函数;“无障碍”吗;?,c++,c++11,language-lawyer,C++,C++11,Language Lawyer,关于删除的移动构造函数的一个删除的回答引用了是可构建的特征应该成功,只要移动构造函数是“可访问的”,即使它不是“可用的” 事实上,该标准要求参数类型的move结构形式良好,因此答案并不完全正确 现在,该标准反复使用术语“可访问”来表示实际的可构造性。例如: [C++11 8.5/6]:默认初始化类型为T的对象意味着: 如果T是(可能是cv限定的)类类型(第9条),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化格式错误) 如果T是数组类型,则默认初始化每个元素 否则,不执行初始
是可构建的
特征应该成功,只要移动构造函数是“可访问的”,即使它不是“可用的”
事实上,该标准要求参数类型的move结构形式良好,因此答案并不完全正确
现在,该标准反复使用术语“可访问”来表示实际的可构造性。例如:
[C++11 8.5/6]:
默认初始化类型为T
的对象意味着:
- 如果
是(可能是cv限定的)类类型(第9条),则调用T
的默认构造函数(如果T
没有可访问的默认构造函数,则初始化格式错误)李>T
- 如果
是数组类型,则默认初始化每个元素李>T
- 否则,不执行初始化
- 如果
T
,T
应为具有用户提供的默认构造函数的类类型
然而,我在标准中找不到任何明确说明delete
d显式定义的构造函数是否“可访问”的地方
另一个[非规范性]引语似乎表明delete
d-ness和可访问性是正交的:
[C++11:12.2/1]:
[…][注:即使没有调用析构函数或复制/移动构造函数,也应满足所有语义限制,如可访问性(第11条)和是否删除函数(8.4.3)。[…]
- 我错过了一段吗
- 如果没有,是否应该更正cppreference.com页面?您能建议更好的措辞吗
- 标准是否应该更清楚地说明这一点
delete
d的影响,而且第一句话实际上根本不包括这样一个构造函数可能是delete
d的情况
相反,在delete
的定义中,这一场景被一种“一网打尽”的要求所涵盖:
[C++11:8.4.3/2]:
隐式或显式引用已删除函数而不是声明该函数的程序是格式错误的。[注意:这包括隐式或显式调用函数,并形成指向函数成员的指针或指针。它甚至适用于未进行潜在计算的表达式中的引用。如果函数重载,则仅当通过重载解析选择函数时才会引用它。-结束注]
因此,cppreference.com可能需要注意的是,除了移动构造函数是否可访问之外,还有一个适用于是否可移动
特征的进一步标准。这里还有一个问题,即可复制
也可以满足†,因此即使是i严格来说,这不是必须的
尽管如此,这一切都提出了另一个有趣的观点,的任何可能实现都是可构造的
必须“引用”已删除的移动构造函数,这使得程序格式不正确,如上所述。尽管如此,我认为使用SFINAE技巧,实现可以避免实际格式不正确
†“完全没有移动构造函数但有复制构造函数的类型是移动可构造的(可从右值构造)。”——我不想讨论cppreference网站所说的内容,但就标准而言,可构造性不是根据“可访问构造函数”定义的.相反,主要的定义是可构造的
,即(C++11,20.9.4.3/6):
在与T
和任何Args
无关的上下文中执行访问检查。只考虑变量初始化的即时上下文的有效性
因此,最后一行代码中假设表达式的良好形式是可构造性特征的定义特征。这与使用删除函数导致程序格式错误的子句密切相关。“而不仅仅是移动构造函数是否可访问”一个完全没有move-ctor但有一个copy-ctor的类型是move-constructible(可以从右值构造)。@DyP:我使用了我在答案中引用的“reference”的定义!它确实包括“如果函数重载,只有通过重载解析选择函数时才会引用它”。哈?(好的,我应该读那张便条的最后一句话,上面也是这么说的;)但是为什么它需要引用已删除的移动向量呢?@DyP如果你有一个像std::vector
这样的容器,当且仅当移动向量是noexcept
时,你就会隐式地使用移动向量,否则元素会被1乘1复制。我看不出你怎么能假设这种东西。例如:I修正了cppreference上的一些相关内容,使之与std更匹配。更好?我相信可访问性指的是名称,而不是定义。调用已删除的函数格式不正确,因此您引用的文本中不再需要任何内容。引用的部分似乎只是为了清晰起见reasons@KerrekSB在标准中,可访问性调用y也指构造函数。但标准从来没有说明它是如何工作的。查看12.1/5:“一个被删除或不可访问的函数”。这些概念似乎确实是独立的。在12.4/5中,再次提到:“有一个被删除的析构函数或一个不可访问的析构函数”@Johanneschaub litb:我认为可访问性也指任意的类成员和基。
is_constructible<T, Args...>
T t(create<Args>()...);