gcc/clang C++:移动未调用但在 A a、b 等代码中需要的构造函数; A c(a+b);

问题描述 投票:0回答:1

我有这个代码:

#include <iostream>
using namespace std;

class A{
  char a;
public:
  A(): a('#') { cerr << "DEFAULT!" << endl; };
  A(char a): a(a) { cerr << "VALUE! " << a << endl;  };
  A(A const &o): a(o.a) { cerr << "COPY! " << o.a << endl; }
  // A(A && o): a(std::move(o.a)) { cerr << "MOVE!: " << o.a << endl; }
  // A(const A && o): a(std::move(o.a)) { cerr << "MOVE!(const): " << o.a << endl; }
  // A(volatile A && o): a(std::move(o.a)) { cerr << "MOVE!(volatile): " << o.a << endl; }
  // A(const volatile A && o): a(std::move(o.a)) { cerr << "MOVE!(const volatile): " << o.a << endl; }
  // A(A && o) = delete; // (***)
  friend A operator+(const A &o1, const A &o2){ A r; r.a = o1.a -'a' + o2.a; cerr << "+:" << r << endl; return r; }
  friend ostream& operator<<(ostream& out, const A& o) { out << o.a; return out; }
};

int main(){
  A a('a');
  A b('b');
  A c('c');
  cout << a << b << c << endl;
  A d(b+c); // <----- !!! WHO HANDLES THIS??? !!!
  A e(a);
  cout << a << b << c << d << e << endl;
  return 0;
}

与“谁处理这个???”一致当值被正确传输时,奇迹就发生了。

我假设默认的移动构造函数被调用,所以我重载了它(然后是所有的 - 请参阅 4 行注释),但令我惊讶的是,没有人得到调用(如果未注释)。然后我尝试删除默认的复制构造函数(无论如何,根据https://en.cppreference.com/w/cpp/language/move_constructor,默认情况下不应创建它,因为我有复制构造函数)。这使得 g++/clang++ 在 WHO HANDLES THIS??? 中返回错误行,其中包含默认移动构造函数已删除的消息。 clang版本10.0.0-4ubuntu1,g++(Ubuntu 9.4.0-1ubuntu1~20.04.2)9.4.0.

这里到底发生了什么?谁能解释或指出任何规格?

c++ constructor default move
1个回答
0
投票

如果将对象地址添加到跟踪输出中,HANDLER 会更容易查看。

这是由于 C++ 标准中允许的优化之一。有一天,C++ 标准甚至可能需要它。 (已更新,谢谢 Artyer。)

#include <iostream>

using std::cerr;
using std::cout;
using std::ostream;

class A { 
    char ch{ '#' };
public:
    A() { cerr << "DEFAULT!\n"; }
    A(char ch_) : ch{ch_} { cerr << "VALUE! " << ch << "\n";  }
    A(A const& from) : ch{from.ch} { cerr << "COPY! " << ch << "\n"; }

    friend auto operator+(A const& a, A const& b) -> A { A r; r.ch = a.ch -'a' + b.ch; cerr << "+:" << r << " @ " << &r << "\n"; return r; }
    friend auto operator<<(ostream& out, const A& a) -> ostream& { return out << a.ch; }
};

int main() {
    A a{'a'};
    A b{'b'};
    A c{'c'};
    cout << a << b << c << "\n";
    cout << "About to make a d...\n";
    A d{b+c}; // <----- !!! WHO HANDLES THIS??? !!!
    cout << "...d@" << &d << " has been made!\n";
    A e{a};
    cout << a << b << c << d << e << "\n";
}   
© www.soinside.com 2019 - 2024. All rights reserved.