9

这是否保证工作:

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。显然它依赖于微妙的声明顺序/名称查找规则,所以我想知道标准对此事有何规定......

4

2 回答 2

8

未定义的行为。

3.3.7/1

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

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

于 2011-08-12T14:08:42.890 回答
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!");

铿锵声

#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
}
于 2011-08-12T14:03:28.997 回答