sstream 重新声明 public 访问编译器错误

sstream redeclared with public access compiler error

我在 运行 使用 gcc5.4.0 制作一个大型项目时遇到了这个错误。

/usr/include/c++/5/sstream:300:14: error: '__xfer_bufptrs' redeclared with 'public' access
      struct __xfer_bufptrs
             ^
/usr/include/c++/5/sstream:67:14: note: previously declared 'private' here
      struct __xfer_bufptrs;

对我来说这似乎是编译器的问题?由于问题出现在标准 C++ 库 sstream 中?这对我来说没有意义,我使用了错误的编译器吗?

以下是错误消息所指的代码片段:

1.) sstream 从第 67 行开始

class basic_stringbuf : public basic_streambuf<_CharT, _Traits>                                   
    {                                                                                                 
      struct __xfer_bufptrs;                                                                          
    public:                                                                                           

2.) 第 300 行的 sstream

#if _GLIBCXX_USE_CXX11_ABI                                                                            
      // This type captures the state of the gptr / pptr pointers as offsets                          
      // so they can be restored in another object after moving the string.                           
      struct __xfer_bufptrs                                                                           
      {                                                                                               
        __xfer_bufptrs(const basic_stringbuf& __from, basic_stringbuf* __to)                          
        : _M_to{__to}, _M_goff{-1, -1, -1}, _M_poff{-1, -1, -1}                                       
        {  

我知道标准库不会有任何问题,但为什么会抛出错误?

这是我最接近的答案: https://github.com/PacificBiosciences/pbbam/issues/14

答案似乎围绕着这些 "Dprivate" 和 "Dpublic" 标志。我假设是编译器标志,但我不确定它们的作用。

github的帖子虽然说到点子上了,但好像没找到原因。您很可能正在项目中构建一些重新定义 'private' 关键字的单元或其他测试,如下所示:

#define private public

或者通过像 (-Dprivate=public) 这样的命令做相应的事情。这是一种常用的做法,可以在不让被测代码依赖于测试代码的情况下,公开私有成员进行测试。 但是看看你的片段。无论您对 private 的定义如何,第一个都将 __xfer_bufptrs 声明为私有。下一个第二个片段肯定(虽然还没有检查)在一个明确的 private 块中。现在,如果你对 private 的定义已经到位,你将在第二个片段中得到 public,这是一个错误。

你至少有两个选择,其他当然也可以:

  1. #undef 在包含系统 headers 之前的私有定义并在包含这些之后再次定义,或者
  2. 您使用另一个宏来定义您自己的 private/public 部分,例如:#define my_public public 可以随意重新定义。虽然这个解决方案看起来很恶心 ;)

哦,为了将来在您自己的代码中始终使用显式访问限定来至少在您自己的代码中避免这种混乱:)