首页 > 解决方案 > g++ 4.8.5 上的全局命名空间问题(可能不完整的 C++11 支持)

问题描述

我使用 -std=c++11 在最新计算机上准备了一个项目。现在,我必须在 g++ 4.8.5(Red Hat 4.8.5-39)上编译它。令我惊讶的是,该系统对 C++11 标准的支持似乎并不完整。请注意,该项目依赖于 gsoap 库,该库在生产系统上也较旧。

我正在使用以下构造:

class GeoGrid : public ::GeoGrid::GeoGridServiceSoapBindingProxy
{
public:
  ...
  using ContextType = ::GeoGrid::GeoGrid2__ContextType;
  ...
}

我在旧系统上收到以下错误:

api-2-0.h:434:23: error: expected type-specifier before ‘::’ token
   using ContextType = ::GeoGrid::GeoGrid2__ContextType;

我不知道这是由于旧的 gsoap 还是旧的 g++ 而产生的。

我的问题是是否可以在不升级系统的情况下解决此问题?我不得不承认,一开始我并没有完全理解使用 '::' 令牌的所有后果,这只是一个幸运的猜测,它在新系统上完美运行。

标签: c++c++11gsoap

解决方案


您的代码段符合以下情况:

/*
struct A {
    struct B {};
}; */

namespace X 
{
struct A {
    using B = ::A::B;    
};
}

使用新的 gcc (v10) 生产

error: 'A' in namespace '::' does not name a type
     using C = ::A::B;

或旧版本(v 4.7+)

 error: expected type-specifier before '::' token
     using C = ::A::B;

上面的错误在全局命名空间中没有A::BGeoGrid::GeoGridServiceSoapBindingProxy在您的情况下)的情况下才会生成,因此::A::B不是合法的类型名,因此编译器认为A是当前上下文范围内的合法类型名以及有关之前缺少所需的上下文标识符的消息范围分隔符::。较新版本的错误消息比技术上正确但具有误导性的旧版本更具可读性。

这种情况的另一个版本是

struct A {
    using C = ::A::B;
    struct B {};
    
};

在存在的行中using CB还没有作为类型存在,导致 GCC 4.8 出现相同的错误消息。较新的版本会告诉该类型不完整。

 error: invalid use of incomplete type 'struct A'
     using C = ::A::B;

在这两种情况下,这表明程序格式不正确,而不是缺乏标准支持。


推荐阅读