【问题标题】:How to force the compiler to show implicit constructors如何强制编译器显示隐式构造函数
【发布时间】:2018-11-06 19:12:52
【问题描述】:

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

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

【问题讨论】:

  • 不完全是你想要的,但看看cppinsights.io
  • @NickyC 谢谢,这很方便。但是不适用于我的情况,因为我正在使用大型代码库。

标签: c++ c++11 gcc clang


【解决方案1】:

您可以使用模板类型特征作为一种解决方法,从某些类型中提取此类信息。这无法区分某些内容是显式删除还是隐式删除,但是您可以确定是否没有显式删除,例如

#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';
}

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

【讨论】:

  • 我参加了一个培训,建议在类定义下明确设置此类编译时检查,有点像“基本单元测试”,但实际上是作为关于类的合同验证器界面。
  • @Jodocus 这正是我目前正在做的事情(比如static_assert(std::is_nothrow_move_constructible))。然而,这是相当手动的,并且仅限于每个班级。在我目前正在使用的大类层次结构中缩小有问题的父类(比如删除了移动构造函数)变得非常麻烦,我想使用 grep/sed/etc。
  • @DevNull 我担心你必须自己构建它。您可以轻松生成可以与例如一起使用的输出。 grep。对于类层次结构:您可以使用一些基本的模板元编程编写一个递归遍历类层次结构树的类模板。
  • @Jodocus 能否请您指出一些用于遍历父类及其成员的类层次结构的基本模板元编程的示例?
  • @DevNull 为什么要遍历类成员?目前这在 C++ 中是不可能的。根据我从您的 cmets 中读到的内容,您还可以了解 C++ 概念(尽管还不是标准的一部分)。
猜你喜欢
  • 2015-06-10
  • 1970-01-01
  • 1970-01-01
  • 2013-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-15
  • 2023-04-11
相关资源
最近更新 更多