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

标签 c++ c++11 gcc clang

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> << '\n';
    std::cout << std::boolalpha << std::is_copy_assignable_v<A> << '\n';
    std::cout << std::boolalpha << std::is_trivially_move_constructible_v<A> << '\n';
}

将产生 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() << '\n';
}

从那时起,您可能会产生自己增强和推广它的想法。

关于c++ - 如何强制编译器显示隐式构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50562189/

相关文章:

c++ - 如何为用户定义的类实现 c++11 move 函数?

c++ - 为什么没有用户提供 cp/mv ctor 且具有虚拟函数但没有虚拟基的类没有 "trival cp/mv ctor"?

c++ - 😃(和其他 Unicode 字符)在 g++ 不允许的标识符中

c++ - 是否可以在实现文件中使用命名空间或等效项来避免在每个函数前加上类名?

c++ - 带括号和不带括号定义的宏 - 重新定义错误

c++ - 什么会导致初始化顺序损坏堆栈?

c - 从优化为循环不变的循环中的结构指针取消引用成员吗?

c++ - 如何检查dll的引用计数?如何知道 dll 的加载位置?

c++ - C++11 中奇怪的初始化

c++ - 使用分析标志编译的代码不会生成 gmon.out