不同的名称查找路径会违反ODR吗?

编程语言 2026-07-12

假设存在两个翻译单元,它们仅在一个命名空间的名称不同:aggregator_1aggregator_2

// Translation unit 1
namespace a {

struct Point
{
    int         x;
    int         y;
};

} // namespace a

namespace aggregator_1 {       // <-- This namespace is different
using ::a::Point;
} // namespace aggregator_1

namespace b {
using namespace aggregator_1;

struct Line
{
    Point       begin;
    Point       end;
};

} // namespace b

以及

// Translation unit 2
namespace a {

struct Point
{
    int         x;
    int         y;
};

} // namespace a

namespace aggregator_2 {       // <-- This namespace is different
using ::a::Point;
} // namespace aggregator_2

namespace b {
using namespace aggregator_2;

struct Line
{
    Point       begin;
    Point       end;
};

} // namespace b

1.这些翻译单元中对 b::Line 的定义是否违反ODR? 假设这些单元被链接在一起。

2.如果使用指令using-directive using namespace a; 取代using-declaration using ::a::Point;,会有影响吗?

我的看法是,在任一情况下都不存在违规,因为它们基本上由相同的标记组成,名称查找会将每个名称解析到同一个实体。名称查找走的是不同的路径,但这似乎与ODR无关。我是不是漏掉了什么重要的因素,可能使这些定义被认定为违规?

解决方案

相关规则([basic.def.odr]/16.4)是:

在每个这样的定义中,按 [basic.lookup] 查找的相应名称,在经过重载解析([over.match])以及部分模板特化的匹配之后,应指向同一个实体。

所以不仅你的示例没问题,甚至只要在每种情况下实际使用的声明相同,你也可以得到不同的查找结果。(对于pre-inline 常量,还有一个额外的例外,以及关于一致语言链接的更多要求,等等。)

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章