相关疑难解决方法(0)

复制elision直接基类初始化?

由于构造函数中的B基类子项目的复制构造,以下代码无法使用Gcc和Clang进行编译A:

struct B{
  B();
  B(const B&) =delete;
  };

struct A:B{
  A():B(B()){} //=> error: use of deleted function...
  };
Run Code Online (Sandbox Code Playgroud)

不过根据[class.base.init]/7:

表达式列表支撑-INIT列表MEM-初始化是根据[dcl.init]用于初始化规则用来初始化指定子对象(或者,在一个委派构造,完整的类对象的情况下)直接初始化.

因此初始化规则对于成员或直接基础是相同的.对于成员子对象,Gcc和Clang不使用已删除的复制构造函数:

struct A2:B{
  B b;
  A2():b(B()){} //=> OK the result object of B() is b
  };
Run Code Online (Sandbox Code Playgroud)

这不是Clang和Gcc的编译器错误吗?是不是B应该省略复制构造函数A()


有趣的是,即使gcc检查复制结构是否格式正确,它也会忽略此复制构造函数调用,请参阅此处的程序集

c++ language-lawyer c++17

16
推荐指数
1
解决办法
332
查看次数

什么时候基类可以具有与相应完整对象类型不同的布局?

当调用基类构造函数时,GCC和Clang不会执行C ++ 17的保证复制省略。有关详细信息,请参见此问题和相应的Clang错误报告

针对错误报告,Richard Smith指出

这是标准措辞中的一个缺陷。初始化基类子对象时,不能保证复制省略,因为基类可以具有与相应完整对象类型不同的布局。

在什么情况下,基类可以以“无法保证复制省略”的方式具有“与相应完整对象类型不同的布局”?有一个具体的例子可以说明这一点吗?

c++ c++17

13
推荐指数
1
解决办法
311
查看次数

是否可以初始化不可复制类型的成员变量(或基类)?

考虑以下代码

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 = {};           // ... …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer c++17

10
推荐指数
1
解决办法
284
查看次数

复制/移动省略是否允许使用格式正确的删除函数制作程序?

请考虑以下代码:

#include <iostream>

struct Thing
{
    Thing(void)                       {std::cout << __PRETTY_FUNCTION__ << std::endl;}
    Thing(Thing const &)              = delete;
    Thing(Thing &&)                   = delete;
    Thing & operator =(Thing const &) = delete;
    Thing & operator =(Thing &&)      = delete;
};

int main()
{
    Thing thing{Thing{}};
}
Run Code Online (Sandbox Code Playgroud)

我希望Thing thing{Thing{}};声明意味着临时对象的建设Thing使用默认的构造函数和建设类thing的对象Thing使用仅仅用创建的临时对象作为参数转移构造类.我希望这个程序被认为是不正确的,因为它包含一个被删除的移动构造函数的调用,即使它可能被省略.标准的class.copy.elision部分似乎也要求这样做:

即使呼叫被省略,也必须可以访问所选的构造函数

通过简化值类别保证复制省略措辞似乎也不允许.

然而gcc 7.2(以及clang 4也是如此,但VS2017 仍然不支持保证复制省略)将编译此代码,只需移动构造函数调用即可.

在这种情况下哪种行为是正确的?

c++ constructor copy-elision c++17

4
推荐指数
1
解决办法
229
查看次数

标签 统计

c++ ×4

c++17 ×4

language-lawyer ×2

constructor ×1

copy-elision ×1