我正在从事的项目需要针对多个目标进行编译。每个目标的基础实现可能会有所不同,因为设备要求对硬件进行不同的配置。
为了强制目标实现遵循接口/设计合同系统,我们对其进行了设计。如果目标没有相应地实现所述接口,则使用时将引发错误。
以下代码已使用gcc,arm-none-eabi-gcc和clang进行了测试
namespace A {
namespace C {
void foo() {}
}
}
namespace B {
using namespace A::C;
void foo() {}
}
using namespace A;
namespace C {
}
int main() {
B::foo(); // ok
C::foo(); // won't compile
return 0;
}
现在,在推理为什么要编译或不编译此代码时会出现多个问题:
为什么编译器不报告A :: foo(bool)和B :: set(bool)之间的不确定性?
为什么C :: foo()不能编译,因为我的理论是可以实现相同的命名结构,但使用的方式不同:
答案 0 :(得分:1)
在第一个代码段中,名称hwstl::target::pin::set
隐藏了名称hwstl::interface_contracts::pin::set
。
对于呼叫hwstl::device::pin::set(true);
,名称查找会在找到hwstl::target::pin::set
后停止。只有一个候选函数,没有歧义。
对于呼叫hwstl::unsatisfied_device::pin::set(true);
,只有一个称为set
的函数仍然可以找到。
10.3.4.1 using伪指令不会将任何成员添加到它所在的声明性区域中。
在第二个代码段中,您通过限定的ID:set
调用hwstl::unsatisfied_device::pin::set
,编译器将仅尝试在命名空间hwstl::unsatisfied_device::pin
中查找名称。因此,它无法在其外部找到使用指令using namespace interface_contracts;
引入的名称。
这是您的代码的简化版本:
namespace A {
void foo() {}
}
namespace B {
using namespace A;
void foo() {}
}
using namespace A;
namespace C {
}
int main() {
B::foo(); // ok
C::foo(); // won't compile
return 0;
}