抑制"基类“类X”应该在复制构造函数中显式初始化"来自库标题的模板类

时间:2015-02-05 14:00:37

标签: c++ templates gcc compilation

我遇到与this one类似的问题。

我正在使用第三方库。它在文件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 docs声明:

  

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

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

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

正如在引用的问题中所述,不可能仅取消此警告,而我必须禁用-Wextra,而我不想这样做。

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

我正在使用gcc 4.1.2。

1 个答案:

答案 0 :(得分:1)

正如其他人所提到的,使用更新的编译器似乎是一种比下面更好的方法,但是当你的手似乎被束缚时,请考虑以下方法:

围绕第三方库类创建包装类

class MyCC {
    CC cc;
};

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

转发任何相关的函数调用,使包装器在您认为必要时变得透明。 或者,您可以使用类似BOOST_STRONG_TYPEDEF的内容。

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

#pragma GCC system_header

希望pragma会在客户端中直接使用该库来禁止警告,而所有其他代码则可以使用包装器,因此不需要编译指示。