繁体   English   中英

代码重构后,前向声明会导致错误

[英]Forward declarations cause errors after code refactor

我原来的课程结构类似于:

//def.h
namespace A
{
   struct X {};
}

并在需要时转发声明:

//file that needs forward declarations
namespace A { struct X; }

进行一些重构之后, X被移到了另一个名称空间,但是为了使旧代码using指令保持“正常工作”,我们使用了:

//def.h
namespace B
{
   struct X {};
}
namespace A
{
   using ::B::X;
}

现在我们可以访问使用旧语法A::X的同一类,但是前向声明会导致错误。 第二个问题是,我收到的错误消息没有指向正向声明的位置,并且查找/替换正向声明非常耗时。

现在,我已经解决了这个问题(困难的方式)。

处理这种情况的最佳方法是什么?

海事组织, using在所有不应该在那里,所有的代码,使用X需要重构,以适应新的命名空间(这是一个解决方案),但不幸的是,这是不是一种选择。

实际的代码要复杂得多,这是一个简化的示例。

我意识到这更多的是关于新代码,而不是重构现有代码,但是我喜欢在这种情况下使用称为X_fwd.hpp的特殊标头。

// X_def.hpp
namespace B
{
   struct X {};
}
namespace A
{
   // NOT: using namespace B; // does not participate in ADL!      
   typedef ::B::X X;  // OR: using ::B::X;
}

// X_fwd.hpp
namespace A { struct X; }

// some file needing declaration of X
#include <X_fwd.hpp>

这使得查找前向声明以及在事后更改它们变得容易得多,因为更改仅被隔离在一个地方(DRY ...)。

注意1 :AFAIK,使用Peter Wood的typedef答案和您的using声明没有技术上的区别。 请注意, using指令using namespace B; 可能会引起麻烦,因为Argument-Dependent-Lookup忽略了这些问题。 更糟糕的是,您的某些代码甚至可能会静默地调用错误的函数重载,因为您不再需要引入新的名称空间B

注2 :在对问题的评论中,给出了一个Ideone示例。 这很好地说明了有关命名空间中名称查找的细微之处:引用标准草案3.4.3.2节“ 命名空间成员[namespace.qual] ”第2节

对于名称空间X和名称m,按以下方式定义名称空间限定的查询集S(X,m):令S'(X,m)为X中m的所有声明和X的内联名称空间集的集合。 (7.3.1)。 如果S'(X,m)不为空,则S(X,m)为S'(X,m); 否则,S(X,m)是S(Ni,m)对于X中使用指令及其内联名称空间集提名的所有名称空间Ni的S(Ni,m)的并集。

这解释了以下棘手的歧义

namespace A
{
    struct X1{};
    struct X2{};
}

namespace B
{
    using A::X1;    // OK: lookup-set is both namespace A and B, and a single unique name is found (at this point!)
    struct X1;      // OK: lookup-set is namespace B, and a single unique name is found

    struct X2;      // OK: lookup-set is namespace B, and a single unique name is found
    using A::X2;    // error: lookup-set is both namespace A and B, and no unique name is found (at this point!)
}

因此,在名称空间中同时具有直接声明和using-声明的有效性取决于顺序。 因此,在fwd头文件中使用单个声明的便利。

最好的方法是修复代码。

您可以分两个步骤进行操作:

  1. 修正所有前向声明
  2. using ::B::X;删除using ::B::X;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM