具有继承的嵌套类的名称查找

时间:2011-08-12 12:30:09

标签: c++ inheritance name-lookup

这是否有效:

struct A
{
  struct Gold {};
};

struct B : public A
{
  typedef Gold BaseGold;
  struct Gold {};
};

struct C : public B
{
  typedef Gold BaseGold;
  struct Gold {};
};

static_assert(is_same<B::BaseGold, A::Gold>::value, "Not the right treasure!");
static_assert(is_same<C::BaseGold, B::Gold>::value, "Not the right treasure!");

它似乎适用于VS2010。显然它依赖于微妙的声明顺序/名称查找规则,所以我想知道标准在这个问题上说了什么......

2 个答案:

答案 0 :(得分:8)

未定义的行为。

3.3.7 / 1

  

以下规则描述了在类中声明的名称范围:

     

2)在S类中使用的名称N应在其上下文中引用相同的声明,并在完成的S范围内重新评估。违反此规则不需要诊断。

答案 1 :(得分:1)

由于还没有引用,我一直在玩你的例子:

gcc 4.5.1和Clang 3.0都接受代码,如下所示。

现在,我们只需要有人来挖掘一个权威的答案。有了Clang,gcc和VC ++同意(不是 频繁),似乎是有意的。

ideone(4.5.1):

#include <utility>

struct A
{
  struct Gold {};
};

struct B : public A
{
  typedef Gold BaseGold;
  struct Gold {};
};

struct C : public B
{
  typedef Gold BaseGold;
  struct Gold {};
};

static_assert(std::is_same<B::BaseGold, A::Gold>::value, "Not the right treasure!");
static_assert(std::is_same<C::BaseGold, B::Gold>::value, "Not the right treasure!");

Clang上:

#include <stdio.h>

template <typename T, typename U>
struct is_same { enum { value = false }; };

template <typename T>
struct is_same<T,T> { enum { value = true }; };

struct A
{
  struct Gold {};
};

struct B : public A
{
  typedef Gold BaseGold;
  struct Gold {};
};

struct C : public B
{
  typedef Gold BaseGold;
  struct Gold {};
};

int main() {
  if (!is_same<B::BaseGold, A::Gold>::value) {
    printf("oups");
  }
  if (!is_same<C::BaseGold, B::Gold>::value) {
    printf("oups");
  }
}

Clang输出(如预期的那样):

define i32 @main() nounwind readnone {
entry:
  ret i32 0
}