c++ - 通过 C++ 中附加子类的友元访问 protected 基类是否合法?

标签 c++ language-lawyer friend protected

考虑我们有一些带有类 B 的第三方库源自A使用protected遗产。所以有一个对象 B我们通常无法访问其基地 A .

但是我们可以创建一些额外的类 C (永远不会构造任何对象)派生自 B并声明与需要访问A的函数的友元-B的一部分- 对象。甚至还有两种获取访问权限的选项:

// some 3rd party library
struct A {};
struct B : protected A {};

// our code to get access to A
struct C : B { friend int main(); };

int main() {
    const B & b = B{};
    [[maybe_unused]] const A & a1 = static_cast<const C&>( b ); // #1: ok everywhere
    [[maybe_unused]] const A & a2 = b; // #2: ok in GCC and MSVC
}

选项 #1 为 static_cast<const C&>适用于所有编译器。但它的格式是否良好(没有未定义的行为)?

选项 #2 更短,但它仅适用于 GCC 和 MSVC,演示:https://gcc.godbolt.org/z/zj146bKsb

鉴于 Clang 拒绝接受它,它是唯一正确满足此处标准的编译器吗?

最佳答案

But is it well formed (no undefined behavior)?

是的,未定义的行为。

[expr.static.cast] (emphasis mine)

2 An lvalue of type “cv1 B”, where B is a class type, can be cast to type “reference to cv2 D”, where D is a class derived from B, if cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. If B is a virtual base class of D or a base class of a virtual base class of D, or if no valid standard conversion from “pointer to D” to “pointer to B” exists ([conv.ptr]), the program is ill-formed. An xvalue of type “cv1 B” can be cast to type “rvalue reference to cv2 D” with the same constraints as for an lvalue of type “cv1 B”. If the object of type “cv1 B” is actually a base class subobject of an object of type D, the result refers to the enclosing object of type D. Otherwise, the behavior is undefined.

在转换 b 时,我们没有实际的 C。因此,我们直接滑到最后一句话,称强制转换本身为未定义。

Given that Clang refuses to accept it, is it the only compiler that fulfills properly the standard here?

是的,确实如此。 Bmain 没有特殊关系,没有友元。因此 A 基础在该范围内是不可访问的。如果基类可访问,则只能将派生类的指针(和引用)转换为基类的指针(和引用):

[conv.ptr]

3 A prvalue of type “pointer to cv D”, where D is a complete class type, can be converted to a prvalue of type “pointer to cv B”, where B is a base class ([class.derived]) of D. If B is an inaccessible ([class.access]) or ambiguous ([class.member.lookup]) base class of D, a program that necessitates this conversion is ill-formed. [...]

关于c++ - 通过 C++ 中附加子类的友元访问 protected 基类是否合法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68967361/

相关文章:

c++ - 用 boost::assign::map_list_of 填充 boost::function 的 std::map

c++ - 可以通过引用传递函数对象吗?

C++ lambda 捕获通过父 lambdas 捕获值的拷贝

c++ - 在参数中移出的智能指针上调用方法是否安全?

c++ - libc++ std::istringstream 不会抛出异常。漏洞?

c++ - 就友元而言,为什么别名模板与别名类型模板的处理方式不同?

c++ - 编译器不识别友元函数

c++ - 访问必须在 if 语句内进行的 int

android - Facebook API 是否允许发送和接受好友请求?

c++ - LNK1112 : module machine type 'x64' conflicts with target machine type 'X86' : Qt creator