C.M*_*.M. 10 c++ language-lawyer c++17
考虑以下代码:
struct S
{
S() = default;
S(S const&) = delete;
// S(S&&) = delete; // <--- uncomment for a mind-blowing effect:
// MSVC starts compiling EVERY case O_O
};
S foo() { return {}; }
struct X : S
{
// X() : S(foo()) {} // <----- all compilers fail here
};
struct Y
{
S s;
Y() : s(foo()) {} // <----- only MSVC fails here
};
struct Z
{
S s = {}; // ... and yet this is fine with every compiler
Z() {}
};
//S s1(foo()); // <-- only MSVC fails here
//S s2 = foo(); // <-- only MSVC fails here
Run Code Online (Sandbox Code Playgroud)
问题:
看起来没有办法用纯右值初始化不可复制的基类——这是正确的吗?看起来标准有缺陷(或者我尝试过的所有编译器都不符合标准)
MSVC 无法初始化成员变量——这是否意味着它不合规?有没有办法解决这个问题?
为什么添加S(S&&) = delete;会导致 MSVC 编译每个案例?
所以,我认为我找到了标准的相关部分,并且我认为编译器在X. (所有链接都是标准草案,所以很可能在 C++17 中有所不同,我稍后会检查。但是 gcc10 和 clang10 也会失败-std=c++20,所以这并不那么重要)。
关于基类的初始化(重点是我的):class.base.init/7
\n\n\nmem-initializer 中的表达式列表或花括号初始化列表用于根据 [ dcl.init] 的初始化规则初始化指定的子对象(或者,在委托构造函数的情况下,初始化完整的类对象)直接初始化。
\n
我认为这告诉我们,这X() : S(foo()) {}不应该与 不同S s = foo(),但是让我们看看dcl.init/17.6.1
\n\n如果初始值设定项表达式是纯右值,并且源类型的 cv 未限定版本与目标类是同一类,则初始值设定项表达式用于初始化目标对象。【示例:
\nT x = T(T(T()));调用T默认构造函数进行初始化x。\xe2\x80\x94结束示例]
这对我来说意味着X() : S(foo()) {}应该调用默认构造函数。我还测试了(完全符合示例)X() : S(S()) {},这在 clang 和 g++ 上也失败了。所以在我看来编译器有缺陷。
| 归档时间: |
|
| 查看次数: |
284 次 |
| 最近记录: |