Maybe my understanding of [class.access]/7 isn'

2019-02-09 02:41发布

From [class.access]/7 we have the following sentence:

Similarly, the use of A::B as a base-specifier is well-formed because D is derived from A, so checking of base-specifiers must be deferred until the entire base-specifier-list has been seen.

class A {
protected:
    struct B { };
};
struct D: A::B, A { };

See live example with clang. As a matter of fact, clang also complains about this snippet, where no deferment is necessary.

class A {
protected:
    struct B { };
};
struct D: A, A::B { };

Why does this code not compile?

PS: gcc and VS21013 don't compile the codes either.

2条回答
男人必须洒脱
2楼-- · 2019-02-09 02:53

I believe this to be a bug with clang. Ideone doesn't accept the code either: http://ideone.com/uiFl9L:

class A {
protected:
struct B { };
};
struct D: A::B, A { };

I checked with gcc-5.1.0, gcc-4.9 and clang-3.7(rc2). The standard explicitly states this as well-formed (see question) thus the compilers are at fault.

The example clearifies [class.access]/6:

All access controls in Clause 11 affect the ability to access a class member name from the declaration of a particular entity, including parts of the declaration preceding the name of the entity being declared ...

This means, according to [class.access]/2 that a class has access to all base-classes, even before they are declared.

查看更多
混吃等死
3楼-- · 2019-02-09 03:09

This is simply a compiler bug. The normative text of the standard supports the example. The fact that multiple compilers have the same bug means this is part of the standard is tricky to get right.

There are open bugs about this for GCC and for clang. Note that a few related cases are actually subtle differences between C++03 and C++11, but as far as I can tell, not this one.

[class.access]/1.2 merely states

protected; that is, its name can be used only by members and friends of the class in which it is declared, by classes derived from that class, and by their friends (see 11.4).

and 11.4 does not expand on this. You are using the name B in a class D derived from that class A. That's fine.

查看更多
登录 后发表回答