C++模板类型与引用匹配[重复]

h7appiyu  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(68)

此问题在此处已有答案

Why is the const lost in an expression like const T& where T is an rvalue reference?(1个答案)
2天前关闭。
当我运行下面的代码时,发生了一个错误。

#include <iostream>
using namespace std;

class M {
 public:
  M(): a(0), b(0) {}
  M(int a, int b): a(a), b(b) {}
 private:
  int a;
  int b;
};

template <typename T>
class Test {
 public:
  Test(const T& my) { }
  T my_;
};

template <typename T>
using ReferTest = Test<T&>;

int main()
{
   ReferTest<M> t2(M(3,4));
}

字符串
错误为:

main.cpp: In function ‘int main()’:
main.cpp:25:20: error: cannot bind non-const lvalue reference of type ‘M&’ to an rvalue of type ‘M’
   25 |    ReferTest<M> t2(M(3,4));
      |                    ^~~~~~
main.cpp:16:17: note:   initializing argument 1 of ‘Test<T>::Test(const T&) [with T = M&]’
   16 |   Test(const T& my) { }
      |        ~~~~~~~~~^~


“cannot bind non-const lvalue reference of type 'M&' to an rvalue of type 'M'”让我很困惑,我知道M(3,4)是一个右值,但是Test的构造函数中的类型是“const T&",而不是“non-const”。

nhn9ugyo

nhn9ugyo1#

我认为你应该在你的模板中使用一个转发引用,而不是像这样的一个常量,它会复制临时对象。像你这样使用临时对象的引用是很棘手的。

#include <iostream>

// don't use using namespace std;

class M 
{
 public:
  M(): a(0), b(0) {}
  M(int a, int b): a(a), b(b) {}

  ~M(){ std::cout << "deleting M\n"; }
  int get_a() const noexcept { return a; };

 private:
  int a;
  int b;
};

template <typename T>
class Test {
 public:
  Test(T&& my) : // <== forwarding here
  my_{std::forward<T>(my) } 
  {
  }

  T my_;
};

template <typename T>
using ReferTest = Test<T>; // <== no reference here!

int main()
{
    ReferTest<M> t2(M{3,4}); // <== M's temporary will be deleted after this line! So it is not safe to have a reference to it after this line.
    std::cout << t2.my_.get_a();
}

字符串

相关问题