禁止从模板类的库标头中"Base class ‘class X’ should be explicitly initialized in the copy constructor"

Suppressing "Base class ‘class X’ should be explicitly initialized in the copy constructor" from library header for template class

本文关键字:class should be explicitly copy constructor the in initialized Base 禁止      更新时间:2023-10-16

我遇到了一个类似的问题。

我正在使用第三方图书馆。它在文件headers/things.h:中定义类如下(由于许可问题,伪造了所有名称)

class A {
public:
    virtual ~A() {}
};

template < class T, class U >
class B : virtual public A {
public:
    B(T) {}
    B(const B< T,U >) {}
    virtual ~B() {}
};

template < class T, class U >
class  C : virtual public B< T, U > {
public:
    C(T t) : B < T, U > (t) {}
    C(const C< T,U > &other) : B< T,U >(other) {}
    ~C() {}
};

另外,仍在库头中:

typedef C< int, int > CC;

错误消息为:

cc1plus: warnings being treated as errors
../headers/things.h: In copy constructor ‘C<T, U>::C(const C<T, U>&) [with T = int, U = int]’:
things.cpp:5:   instantiated from here
../headers/things.h:22: warning: base class ‘class A’ should be explicitly initialized in the copy constructor
../headers/things.h: In copy constructor ‘B<T, U>::B(const B<T, U>&) [with T = int, U = int]’:
../headers/things.h:23:   instantiated from ‘C<T, U>::C(const C<T, U>&) [with T = int, U = int]’
things.cpp:5:   instantiated from here
../headers/things.h:12: warning: base class ‘class A’ should be explicitly initialized in the copy constructor

things.cpp中,我有:

#include "things.h"
CC make_cc() {
    CC cc(123);
    return cc;
}
int main() {
    CC cc = make_cc();
    return 0;
}

文件布局为:

../
|-- source
|   `-- things.cpp
`-- headers
    `-- things.h

我知道这个警告意味着什么,我并没有要求这样做。由于它在第三方库中,出于维护原因,我非常不愿意修改(修复)它。我只是想忽略这个警告。

我正在用编译我的代码

g++ things.cpp -o things -Wall -Wextra -Werror -isystem ../headers/

我使用-isystem来指定目录,因为gcc文档声明:

GCC处理系统标头时,除"#警告"(请参阅诊断)生成的警告外,所有警告都将被抑制。(…)-isystem命令行选项将其参数添加到目录列表中以搜索标头,就像-I一样。在该目录中找到的任何标头都将被视为系统标头。

这似乎总的来说是有效的,因为几乎所有来自第三方图书馆的警告都被压制了。

不幸的是,由于此声明恰好是typedef模板化类的实例化,编译器认为它正在编译的是my代码,而不是(伪)系统头。

正如在引用的问题中所说,不可能只抑制这个警告,我必须禁用-Wextra,这是我不想做的

问题:是否可以抑制此警告?让gcc知道这不是我的代码,而是库代码?

我使用的是gcc 4.1.2。

正如其他人所提到的,使用较新的编译器似乎是比以下方法更好的方法,但由于您的手似乎被束缚住了,请考虑以下方法:

沿着的路线围绕第三方库类创建包装器类

class MyCC {
    CC cc;
};
template<typename T, typename U>
class MyB {
    B<T, U> b;
};

转发任何相关的函数调用,使包装器尽可能透明。或者,您可以使用类似BOOstrongTRONG_TYPEDEF的东西。

定义这些包装器的头可以位于文件的顶部:

#pragma GCC system_header

希望pragma能在直接使用库的仅客户端中抑制警告,而所有其他代码都可以使用包装器,因此不需要pragma。