生成有关使用复制构造函数和赋值的警告

Mir*_*ral 5 c++ copy-constructor suppress-warnings visual-c++ visual-studio-2017

有没有办法让编译器(特别是 MSVC 2017,但其他也可能很有趣)在使用特定类的复制构造函数和复制赋值运算符的位置发出警告并且以一种可以在每个调用站点被显式抑制,即使是间接的)?

这个问题询问有关产生编译错误的问题,现在使用 C++11 删除的方法很容易,但我希望代码仍然可以编译,只是输出警告。

原因是我有一个类,目前在整个代码库中被大量复制。我不想阻止它被复制(其中一些是必要的),但我确实想检查每个位置以确定是否应该将其更改为移动或通过引用传递。

让编译器暂时将构造函数的使用标记为警告似乎是一个很好的方法。

我尝试添加这样的内容:

__declspec(deprecated) MyType(MyType const&) = default;
Run Code Online (Sandbox Code Playgroud)

但这是行不通的;显然= default胜过任何其他修饰符。

我做了同样的事情,但完全实现了该方法,这几乎有效 - 它在每个调用站点生成 C4996,我可以查看这些并更改它们或附加:

#pragma warning(suppress:4996)
Run Code Online (Sandbox Code Playgroud)

如果我很高兴这是必需的副本。(我最终计划删除这些以及构造函数的弃用——这只是跟踪我尚未处理的内容的内务处理。)

不幸的是,有些情况我无法通过这种方式抑制,例如:

std::vector<MyType> list;
list.push_back(type);
list.emplace_back(MyType{ type });
Run Code Online (Sandbox Code Playgroud)

这些行中的每一行都会引发警告(第一行是因为它是具有常规复制构造函数的类内的字段声明),但这里只能直接抑制第三行。前两个在该行代码中引发警告<vector>,并且似乎不受警告抑制(或禁用)的影响。

有什么方法可以解决这个问题,或者有其他方法可以做我想要的事情吗?

Mir*_*ral 1

在以其他方式完成之后再考虑一下,以其他方式执行此操作可能会更好(也更容易):

  1. 全部替换MyType为(当然,WarnMyType除了 的实际定义)。MyType
  2. 添加WarnMyType已弃用的构造函数:

    struct WarnMyType : MyType
    {
        using MyType::MyType;
        __declspec(deprecated) WarnMyType(WarnMyType const& o) : MyType(o) {}
        __declspec(deprecated) WarnMyType& operator=(WarnMyType const& o)
            { MyType::operator=(static_cast<MyType const&>(o)); return *this; }
        WarnMyType(WarnMyType&&) = default;
        WarnMyType& operator=(WarnMyType&&) = default;
    };
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在检查时逐渐改变WarnMyTypeback的用法。MyType

  4. 消除WarnMyType
  5. 批量替换WarnMyTypeback to的任何剩余用法MyType(因为 #3 只会找到执行复制的那些用法)。

如果这些工具能够像查找命名方法的使用一样轻松地查找构造函数/运算符的使用,那就太好了......