std :: is_nothrow_copy_copy_constructible的实现是什么?

What is the implementation of std::is_nothrow_copy_constructible?

本文关键字:copy 实现 是什么 constructible nothrow std is      更新时间:2023-10-16

我读过std :: is_nothrow_copy_constructible,并了解我们可以使用此函数来检查复制构造函数是否投掷。我写了一些演示,如下所示:

#include <iostream>
struct A { };
struct B { B(const B&){} };
struct C { C(const C&) noexcept {} };
struct D { int a;};
struct E { std::string a;};
struct F { F(const F&)= default; };
struct G { std::string a; G(const G&)= default; };
int main() {
    std::cout << std::boolalpha;
    std::cout << "is_nothrow_copy_constructible:" << std::endl;
    std::cout << "int: " << std::is_nothrow_copy_constructible<int>::value << std::endl;
    std::cout << "A: " << std::is_nothrow_copy_constructible<A>::value << std::endl;
    std::cout << "B: " << std::is_nothrow_copy_constructible<B>::value << std::endl;
    std::cout << "C: " << std::is_nothrow_copy_constructible<C>::value << std::endl;
    std::cout << "D: " << std::is_nothrow_copy_constructible<D>::value << std::endl;
    std::cout << "E: " << std::is_nothrow_copy_constructible<E>::value << std::endl;
    std::cout << "F: " << std::is_nothrow_copy_constructible<F>::value << std::endl;
    std::cout << "G: " << std::is_nothrow_copy_constructible<G>::value << std::endl;
    return 0;
}

结果是:

is_nothrow_copy_constructible:
int: true
A: true
B: false
C: true
D: true
E: false
F: true
G: false

我想知道为什么e被抛出,但d却不是。我猜:

  1. 如果将自定义复制构造函数声明为noExcept,则std :: is_nothrow_copy_copy_constructible将假设它是不可以的,否则会被抛弃。
  2. 如果某个类包含某些复制构造函数可能会投掷的数据成员,则类的默认复制构造函数是可投掷的,例如E级E。

我不知道我的猜测是否为真。蚂蚁我想知道我可以在哪里找到std::is_nothrow_copy_constructible的实现?

让我们看一下标准库的stdlibc 实现(可以在<type_traits>中找到):

  template<typename _Tp, typename... _Args>
    struct __is_nt_constructible_impl
    : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))>
    { };
  template<typename _Tp, typename _Arg>
    struct __is_nt_constructible_impl<_Tp, _Arg>
    : public integral_constant<bool,
                               noexcept(static_cast<_Tp>(declval<_Arg>()))>
    { };

实现只需检查对(复制)构造函数的调用是noexcept(使用noexcept操作员),并从true_type还是false_type相应地继承。您的假设是正确的,编译器足够聪明,可以尽可能使默认的构造函数noexcept,即,它不必调用未标记为noexcept的成员对象的构造函数。