C++ 具名要求:可复制构造 (CopyConstructible)

来自cppreference.com
< cpp‎ | named req


 
 
C++ 具名要求
 

指定该类型的实例可以从左值表达式进行复制构造。

要求

以下情况下,类型 T 满足可复制构造 (CopyConstructible)

给定

  • vTconst T 类型的左值表达式或 const T 类型的右值表达式
  • 任意标识符 u

下列表达式必须合法且拥有指定的效果:

表达式 后条件
T u = v; u 的值等价于 v 的值。不更改 v 的值。
T(v) T(v) 的值等价于 v 的值。不更改 v 的值。

表达式 v.~T() 也必须合法,且对于左值 v,表达式 &v 必须具有 T*const T* 类型,且必须求值为 v 的地址。

(C++11 前)

注解

C++11 前,重载了 operator& 的类不满足可复制构造 (CopyConstructible) ,从而不可用于标准库容器。这是 C++98 的设计决定(而不是缺陷,见 LWG 问题 390)。

C++11 开始,标准库在凡是需要对象地址时都会使用 std::addressof

延伸内容

作为可复制构造 (CopyConstructible) 类模板蕴含 std::is_copy_constructible,但反之不然,因为 std::is_copy_constructible 仅检查以正确实参调用构造函数的能力,而非诸如可移动构造 (MoveConstructible) 的要求。

#include <type_traits>
#include <utility>
 
struct S
{
    S() = default;
    S(S&&) = delete;
    S(const S&) = default;
};
static_assert(std::is_copy_constructible_v<S>);
 
int main()
{
    S s1;
 
    // 类 `S` 并不满足可移动构造(MoveConstructible)的要求,
    // 因而并不满足可复制构造(CopyConstructible)的要求
    [[maybe_unused]] S s2{std::move(s1)}; // 非良构,使用了弃置的函数
}

引用

延伸内容
  • C++23 标准(ISO/IEC 14882:2024):
  • 16.4.4.2 Template argument requirements [utility.arg.requirements]

参阅

检查类型是否拥有复制构造函数
(类模板)
指定能复制构造和移动构造一个类型的对象
(概念)