gpt4 book ai didi

c++ - move 具有常量数据成员或引用成员的类的构造函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:45:03 25 4
gpt4 key购买 nike

我在理解何时以及是否调用 move 构造函数或 move 赋值运算符时遇到一些问题,特别是在具有常量数据成员的类的上下文中。考虑类

template<typename T> class A {
const*T const P ; // constant data member
explicit A(const*T p) : P(p) { std::cerr<<" ctor: P="<<P<<'\n'; }
void test() const { std::cerr" test: P="<<P<<'\n'; }
// move and copy constructors and assignment operators here
};

和测试程序

class B {
int X[100];
A<B> get_a() const { return A<B>(this); }
};

int main() {
B b;
A<B> a = b.get_a(); // which operator/ctor is used for '=' here?
a.test();
}

那么编译的结果是不同的,这取决于为类 A<> 中的 move 构造函数和 move 赋值运算符提供的定义。 ,还有编译器。

1 类中没有任何进一步的声明 A<> (如上所述),g++ (4.7.0) 和 icpc (13.0.1) 都可以正常编译(使用选项 -std=c++11 )并产生预期的输出

ctor: P=0x7fffffffd480
test: P=0x7fffffffd480

2如果我声明

A&A::operator=(A&&) = delete;
A&A::operator=(const A&) = delete;

(鉴于必须初始化列表初始化的常量数据成员,这似乎是明智的),但不提供任何进一步的构造函数,g++ 编译失败但 icpc 没问题。如果另外我定义了一个(或两个)

A::A(A&&) = default;
A::A(const A&) = default;

两个编译器都很高兴。但是,g++ 对这种组合并不满意

A::A(A&&) = delete;
A::A(const A&) = default;

虽然 icpc 很高兴。

3 如果我玩与2相同的游戏,除了A::A(A&&) = default;被替换为

A::A(A&&a) : P(a.P) { std::cerr<<" move ctor: P="<<P<<'\n'; } // never called?

(和 A::A(const A&) 的等价物),结果完全相同,特别是没有输出是从这些显式 move 和复制 ctors 生成的。

那么=用的是哪个运算符在 main() ? (为什么上次测试没有输出?)

考虑到A<>,为什么这里允许这个操作呢?有一个常量数据成员(如果我将成员 const*T const P; 替换为 const T&R ,结果是相同的)?

最后,对于 g++ 和 icpc 的不同行为,如果有的话,哪个是正确的?

最佳答案

A<B> a = b.get_a();

不是赋值,而是从右值初始化 a。此语法在 C++0x 下应该失败,如果

  1. move 构造函数被删除,
  2. move 构造函数被声明为显式
  3. 复制构造函数被删除,并且没有定义 move 构造函数,
  4. 没有定义 move 构造函数,同时定义或删除了 move 赋值。

复制赋值运算符的声明或删除不应有任何影响。

更正:与复制构造函数(即使提供了用户定义的复制赋值运算符也会合成)不同,如果定义了用户定义的 move 赋值,编译器不会合成 move 构造函数。因此,上面的列表应该修改 4(我现在已经这样做了)。

因此,在我看来,

  • 在问题 [1] 中,两个编译器都正确运行,
  • 在 [2]/1 中,gcc 行为正确( move 赋值阻止生成 move 构造函数),icpc 错误,
  • 在[2]/2中,两个编译器都是正确的,
  • 在 [2]/3 中,gcc 是正确的,因为 move 构造函数被显式删除; icpc错了,
  • [3] 对我来说是个谜。你确定你是对的吗?

关于c++ - move 具有常量数据成员或引用成员的类的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13565594/

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