Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从模板类继承时如何应用移动语义_C++_C++11_Templates_Move Semantics - Fatal编程技术网

C++ 从模板类继承时如何应用移动语义

C++ 从模板类继承时如何应用移动语义,c++,c++11,templates,move-semantics,C++,C++11,Templates,Move Semantics,当我运行下面的代码时,它会生成以下输出, 第一部分直接使用模板, 第二种方法使用从模板派生的类。 在派生类中不调用移动语义(以粗体显示) 模板虚拟:正在初始化构造函数 模板虚拟:正在初始化构造函数 模板伪:空构造函数 模板伪:空构造函数 模板虚拟:+运算符 模板虚拟:移动分配 2 模板虚拟:正在初始化构造函数 模板虚拟:正在初始化构造函数 模板伪:空构造函数 模板伪:空构造函数 模板虚拟:+运算符 模板伪:复制构造函数 模板虚拟:复制分配 2 我认为,原因很清楚——命名参数会将参数转换为左值,因

当我运行下面的代码时,它会生成以下输出, 第一部分直接使用模板, 第二种方法使用从模板派生的类。 在派生类中不调用移动语义(以粗体显示)

模板虚拟:正在初始化构造函数
模板虚拟:正在初始化构造函数
模板伪:空构造函数
模板伪:空构造函数
模板虚拟:+运算符
模板虚拟:移动分配
2

模板虚拟:正在初始化构造函数
模板虚拟:正在初始化构造函数
模板伪:空构造函数
模板伪:空构造函数
模板虚拟:+运算符
模板伪:复制构造函数
模板虚拟:复制分配
2

我认为,原因很清楚——命名参数会将参数转换为左值,因此模板接收左值并调用副本构造函数

问题是在这种情况下如何强制移动语义

  #include <iostream>

  using namespace std;

  template <typename T> class Dummy {

  public:

    T val;

    Dummy& operator=(const Dummy& d){
      val = d.val;
      cout << "Template Dummy: copy assignment\n" ;
      return *this;
    }

    Dummy operator+(const Dummy &d) {
      Dummy res;
      res.val = val + d.val;
      cout << "Template Dummy: +  operator\n" ;
      return res;
    }

    // constructors
    Dummy() {
      val = 0;
      cout << "Template Dummy: empty constructor\n" ;
    }

    Dummy(const T v) {
      val = v;
      cout << "Template Dummy: initializing constructor\n" ;
    }

    Dummy(const Dummy &d) {
      val = d.val;
      cout << "Template Dummy: copy constructor\n" ;
    }

    // move semantics
    Dummy(const Dummy&& d) {
      val = d.val;
      cout << "Template Dummy: move constructor\n" ;
    }

    Dummy& operator=(const Dummy&& d){
      val = d.val;
      cout << "Template Dummy: move assignment\n" ;
      return *this;
    }
  };

  class FloatDummy : public Dummy<float> {
  public:

      FloatDummy& operator=(const FloatDummy& d){
        Dummy<float>::operator=(d);
        return *this;
      }

      FloatDummy operator+(const FloatDummy &d) {
        return (FloatDummy) Dummy<float>::operator+(d);
      }

      // constructors
      FloatDummy() : Dummy<float>() {};
      FloatDummy(float v) : Dummy<float>(v) {}
      FloatDummy(const FloatDummy &d) : Dummy<float>(d) {}
      FloatDummy(const Dummy<float> &d) : Dummy<float>(d) {}

      // move semantics
      FloatDummy(const FloatDummy&& d) : Dummy<float>(d) {}

      FloatDummy& operator=(const FloatDummy&& d){

      // here d is already an lvalue because it was named
      // thus the template invokes a copy assignment    
      Dummy<float>::operator=(d);
      return *this;
    }
  };

  int main() {
    Dummy<float> a(1), b(1);
    Dummy<float> c;
    c = a + b;
    cout << c.val << '\n';;

    FloatDummy d(1), e(1);
    FloatDummy f;
    f = d + e;
    cout << f.val << '\n';
  }
#包括
使用名称空间std;
模板类虚拟{
公众:
T值;
虚拟和运算符=(常量虚拟和d){
val=d.val;

cout您不能从
常量移动&
。要修复此问题,只需从所有移动操作中删除
常量

FloatDummy(FloatDummy&& d) : Dummy<float>(d) {}
//         ^^^^^^^^^^^^ no longer FloatDummy const&&

FloatDummy& operator=(FloatDummy&& d) { /*...*/ }
//                    ^^^^^^^^^^^^ ditto

const&
的所有案例中删除
const
,并使用
std::move(d)
d
移动。这解决了问题。我还有一个缺少的移动构造函数,它不是从模板复制的,导致了复制。现在我有一个移动构造函数和一个移动分配。谢谢!!
FloatDummy(FloatDummy&& d) : Dummy<float>(std::move(d)) {}
//                                        ^^^^^^^^^ calling std::move()
//                                                  otherwise copy ctor overload is chosen

FloatDummy& operator=(FloatDummy&& d)
{
    Dummy<float>::operator=(std::move(d));
    //                      ^^^^^^^^^ ditto
    return *this;
}