如何强制编译器显示隐式构造函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何强制编译器显示隐式构造函数相关的知识,希望对你有一定的参考价值。

gcc或clang有“-E”选项来运行预处理器并显示所有宏是如何扩展的,对于隐式生成的方法我需要这样的东西。

有没有办法强制gcc或clang为每个类打印隐式创建和删除的构造函数/析构函数/赋值运算符?

答案

您可以使用模板类型特征作为变通方法从某些类型中提取此类信息。这无法区分某些内容是明确删除还是含蓄,但您肯定知道如果没有明确删除,就像

#include <iostream>
#include <type_traits>

struct A { 
    A(const A&) = delete;
};

int main() {
    std::cout << std::boolalpha << std::is_trivially_default_constructible_v<A> << '
';
    std::cout << std::boolalpha << std::is_copy_assignable_v<A> << '
';
    std::cout << std::boolalpha << std::is_trivially_move_constructible_v<A> << '
';
}

将产生false, true, false,即例如当复制构造函数被明确删除时,隐含地删除了普通的默认构造函数。

编辑:这是一个通过类层次结构并找到违反某个特征的基类的示例:

#include <iostream>
#include <type_traits>
#include <typeinfo>

struct A {
    A(const A&) = delete;
    A(A&&) noexcept { }
};

struct B : A {
    using base_type = A;
    B(B&& b) : A(std::move(b)) { }
};

struct C : B {
    using base_type = B;
};

struct D : C {
    using base_type = C;
};

template <typename T, bool = std::is_nothrow_move_constructible_v<typename T::base_type>>
struct check { };

template <typename T>
struct check<T, false> : check<typename T::base_type> { };

template <typename T>
struct check<T, true> {
    using result_t = T;
};

int main() {
    std::cout << typeid(check<D>::result_t).name() << '
';
}

从那以后,您可能会想到自己增强和概括它。

以上是关于如何强制编译器显示隐式构造函数的主要内容,如果未能解决你的问题,请参考以下文章

怎样让vs2013不进行强制类型转换

7. 类

C++11 新特性 之 explicit关键字 - 显示构造与隐式构造

c++中的类型转换

是否有任何可能的方法来强制使用字符串文字进行隐式构造函数初始化

显式声明和隐式声明都是啥时候用?该用哪一个?