c – 当一个完美的转发构造函数存在时,前向左值引用构造函数的意图是什么?

前端之家收集整理的这篇文章主要介绍了c – 当一个完美的转发构造函数存在时,前向左值引用构造函数的意图是什么?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我们来看std :: pair< T1,T2>举个例子.它有以下两个构造函数
  1. constexpr pair( const T1& x,const T2& y ); // #1
  2. template< class U1,class U2 > constexpr pair( U1&& x,U2&& y ); // #2

看起来#2可以处理#1可以处理的所有情况(没有更差的性能),除了参数是list-initializer的情况.例如,

  1. std::pair<int,int> p({0},{0}); // ill-formed without #1

所以我的问题是:

>如果#1仅用于list-initializer参数,由于x和y最终绑定到从list-initializers初始化的临时对象,为什么不使用constexpr对(T1&& x,T2&& y);代替?
>否则,#1的实际意图是什么?

解决方法

如果要存储的对象是临时对象但不可移动怎么办?
  1. #include <type_traits>
  2. #include <utility>
  3. #include <iostream>
  4.  
  5. class test
  6. {
  7. public:
  8. test() { std::cout << "ctor" << std::endl; }
  9. test(const test&) { std::cout << "copy ctor" << std::endl; }
  10. test(test&&) = delete; // { std::cout << "move ctor" << std::endl; }
  11. ~test() { std::cout << "dtor" << std::endl; }
  12.  
  13. private:
  14. int dummy;
  15. };
  16.  
  17. template <class T1,class T2>
  18. class my_pair
  19. {
  20. public:
  21. my_pair() {}
  22. // Uncomment me plz !
  23. //my_pair(const T1& x,const T2& y) : first(x),second(y) {}
  24. template <class U1,class U2,class = typename std::enable_if<std::is_convertible<U1,T1>::value && std::is_convertible<U2,T2>::value>::type>
  25. my_pair(U1&& x,U2&& y) : first(std::forward<U1>(x)),second(std::forward<U2>(y)) {}
  26.  
  27. public:
  28. T1 first;
  29. T2 second;
  30. };
  31.  
  32. int main()
  33. {
  34. my_pair<int,test> tmp(5,test());
  35. }

上面的代码没有编译,因为my_pair的所谓“完美”转发构造函数将临时测试对象转发为rvalue引用,而rvalue引用又试图调用显式删除的test的构造函数.

如果我们从my_pair中删除注释不是那么“完美”的构造函数,那么它最好通过重载解析来实现,并且基本上强制临时测试对象的副本,从而使其工作.

猜你在找的C&C++相关文章