这是否有效:
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。显然它依赖于微妙的声明顺序/名称查找规则,所以我想知道标准在这个问题上说了什么......
答案 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
}