如何检查一个名称是否与另一个名称相同?

时间:2017-01-23 19:49:19

标签: c++ clang

我想检查完全限定名称和不合格或部分限定名称是否引用相同的符号,即使一个名称未定义。也就是说,我希望能够将这样的内容写成重构工具的一部分:

namespace A {
void f() {};
}

namespace B {
namespace A {};

  bool g() {
    // returns false
    return is_same_symbol<A::f, ::A::f>::value;
  }
}

namespace C {
  bool h() {
    // returns true
    return is_same_symbol<A::f, ::A::f>::value;
  }
}

1 个答案:

答案 0 :(得分:0)

您在评论中澄清:

  

我试图找出正确的SFINAE咒语,以检查是否存在给定名称的自由函数。

你不能。

当你说一个名为 foo 的免费功能时,你是什么意思?

必须是以下之一:

编译器已经看到了 foo的声明:

... int foo(int i);

或:

编译器已经看到了 foo的定义:

... int foo(int i) {
    ...
    return ...;
}

定义也是一个声明,所以如果编译器没有 看到foo的声明,它也没有看到定义。

假设您正在尝试SFINAE - 探测是否声明了foo。 如果编译器甚至没有看到foo的声明,那么任何 您编写的后续代码使用foo作为名称将引发 一个编译错误:

error: use of undeclared identifier 'foo'

您无法将代码写入SFINAE - 探测是否声明foo 你不能编写使用未声明名称的C ++,句号。

假设您正在尝试SFINAE探测foo是否已定义。 要做到这一点,你首先必须拥有foo的声明 - 或者 你自己写的,或者你从某个头文件中得到的。

但是当然,鉴于foo的声明,编译器无法判断是否 是否定义并且不关心,除非在功能的特殊情况下 声明为staticinline或匿名命名空间。 否则,它会向链接器发现或未找到定义。

通常情况下,SFINAE探测函数定义的存在同样如此 一个非首发。即使宣布foo static 或者inline或者在匿名命名空间中,并且在编译单元中缺少任何定义 使用foo 符合其声明的代码仍然是格式良好的 码;所以即使在那些情况下,SFINAE探测它定义的仍然没有意义。