gpt4 book ai didi

c++ - 通过派生类构造函数继承访问自己的私有(private)构造函数

转载 作者:行者123 更新时间:2023-12-03 10:04:39 24 4
gpt4 key购买 nike

Consider :

struct B {
void f();
private:
B(int, int = 0);
};
struct D : B { using B::B; };
void B::f() {
auto a = D{0};
auto b = D(0);
auto c = D(0, 0);
D x{0};
D y(0);
D z(0, 0);
}
GCC 接受(从 7.1 开始;以前全部拒绝)。
Clang 接受 bxyz但拒绝 ac .
MSVC 在 C++14 模式下拒绝所有,但在 C++17 模式下接受所有。
哪些编译器是正确的? C++14 和 C++17 之间的规则是否改变了 - 如果是,为什么在 C++14 中是 B::f不允许访问自己的构造函数(通过 D 命名)?为什么 Clang 只接受 b 的 (function-style) cast而不是列表初始化 a或构造函数调用 c ?
(使 B 成为 friendD 使 Clang 接受,但旧版本(3.8 和更早版本)和 C++14 模式下的 MSVC 除外。它对 gcc 没有影响。)
现在,我知道 C++14 says :

A constructor so declared [as an inheriting constructor] has the same access as the corresponding constructor in [the base class] X.


而在 C++17 中,规则得到了简化、澄清和 moved to [namespace.udecl] :

A using-declarator that names a constructor does not create a synonym; instead, the additional constructors are accessible if they would be accessible when used to construct an object of the corresponding base class, and the accessibility of the using-declaration is ignored.


所以,我认为也许“具有相同的访问权限”意味着继承的构造函数是 privateD所以只有 D 可以访问(及其 friend ),而不是 privateB ( B::f 可以访问)和它们在 B 中的相应构造函数一样.但是在这种解释下,人们可以通过继承来颠覆访问检查并访问基类的私有(private)构造函数。所以可以肯定的是,在 C++14 中,措辞的意图与在 C++17 中更清楚地表达的意图相同——但是为什么 MSVC 会根据语言版本改变其行为呢?

最佳答案

有一个 lot of issues使用继承构造函数的原始规范(当时它们被称为),其中一些涉及访问控制。他们是 fixed retroactively ,这应该是 C++14 的官方版本(作为当时最新发布的标准)。许多编译器选择将此类更改应用于有意义的早期版本(即 C++11)。
但是,即使在已发布的 C++14 中也无法访问私有(private)基类构造函数,因为继承私有(private)构造函数的隐式定义将 失败调用基中的实际私有(private)构造函数。因此 MSVC 是正确的,只是没有将缺陷报告应用于 C++14; Clang 在处理某些类型的初始化时似乎有一个单独的错误;也许它接受D(0)因为它是根据 D …(0); 定义的.当前的 GCC 在所有情况下都是正确的。

关于c++ - 通过派生类构造函数继承访问自己的私有(private)构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65320302/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com