禁止"基类"类X'应该在模板类的库头中从复制构造函数中显式初始化

rub*_*nx9 10 c++ gcc templates compilation

我遇到了类似这个问题.

我正在使用第三方库.它在这里定义类(由于许可问题而伪造所有名称),在文件中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() {}
};
Run Code Online (Sandbox Code Playgroud)

另外,还在图书馆标题中:

typedef C< int, int > CC;
Run Code Online (Sandbox Code Playgroud)

错误消息是:

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
Run Code Online (Sandbox Code Playgroud)

things.cpp,我有:

#include "things.h"

CC make_cc() {
    CC cc(123);
    return cc;
}

int main() {
    CC cc = make_cc();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

文件布局是:

../
|-- source
|   `-- things.cpp
`-- headers
    `-- things.h
Run Code Online (Sandbox Code Playgroud)

我知道这个警告意味着什么,我不是要求这个.由于它位于第三方库中,因此无法根据维护原因修改(修复)它.我只是想忽略这个警告.

我正在编译我的代码:

g++ things.cpp -o things -Wall -Wextra -Werror -isystem ../headers/
Run Code Online (Sandbox Code Playgroud)

-isystem用于指定目录,因为gcc docs声明:

GCC处理系统标题时,除"#warning"(参见"诊断")生成的警告之外的所有警告都将被禁止.(...) - isisystem命令行选项将其参数添加到目录列表以搜索标题,就像-I一样.在该目录中找到的任何标头都将被视为系统标头.

这似乎总体上起作用,因为几乎所有来自第三方库的警告都被压制了.

不幸的是,由于这个声明恰好是typedef'模板化类的实例化,编译器认为它是编译的代码,而不是(假的)系统头.

正如在引用的问题中所说,不可能仅仅禁止此警告,-Wextra而是我必须禁用,我不想这样做.

问题:无论如何都可以抑制此警告吗?要让gcc知道它不是我的代码,而是库代码?

我正在使用gcc 4.1.2.

小智 1

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

按照以下方式围绕第三方库类创建包装类

class MyCC {
    CC cc;
};

template<typename T, typename U>
class MyB {
    B<T, U> b;
};
Run Code Online (Sandbox Code Playgroud)

转发任何相关的函数调用,以使包装器按照您认为必要的方式透明。或者,您可以使用类似BOOST_STRONG_TYPEDEF的东西。

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

#pragma GCC system_header
Run Code Online (Sandbox Code Playgroud)

希望该编译指示能够在唯一直接使用该库的客户端中抑制警告,而所有其他代码都可以使用包装器,从而不需要该编译指示。