琐碎的可复制是否意味着不可复制?

时间:2017-12-08 21:30:57

标签: c++ c++17

或者,是否有一个带有可以抛出的复制构造函数的类型的示例,但是仍然是微不足道的? 如果不是,这是否意味着只要is_nothrow_copy_constructible_v<T>为真,is_trivially_copy_constructible_v<T>就应该为真?

请注意,根据标准(latest draft [23.15.4.3]),对于不可复制的类型T,我们需要表达式T t(declval<const T&>());是一个格式良好的变量定义, 已知不会抛出任何异常。这个措辞对我来说似乎有些贬低 - 对于知道的东西意味着什么? noexcept说明符是否足以建立知识?或者可能决定是由实施决定的?

编辑:我意识到,通过简单的可复制和轻松复制可构造之间存在差异。我的重点是后者。

2 个答案:

答案 0 :(得分:6)

  

琐碎的可复制是否意味着不可复制?

没有。例如:

struct X {
    X(X&& ) = default;
    X(X const& ) = delete;
};

这种类型可以轻易复制,但不能无法复制......甚至可以复制。

但是,给予类型是可复制的 可以轻易复制,那么它必须是可复制的而不会抛出(任何潜在的例外都会有来自一个不平凡的副本,它不存在)。

简单地默认复制构造函数,但标记为noexcept(false)将其定义为as deleted,因此这种类型不可复制。

答案 1 :(得分:3)

在实现DR2171的编译器上:

struct X {
    X(X&) = default;
    template<class U> X(U&&){ throw 1; }
};

static_assert(std::is_trivially_copyable_v<X>, "");
static_assert(std::is_copy_constructible_v<X>, "");
static_assert(!std::is_nothrow_copy_constructible_v<X>, "");
static_assert(!std::is_trivially_copy_constructible_v<X>, "");