c++ - tuple/tie的返回值优化

标签 c++ c++11 stdtuple rvo

我正在研究元组/关系的返回值优化,我观察到的行为与我预期的不同。在下面的示例中,我希望移动语义能够发挥作用,它确实如此,但是仍然存在一个复制操作。以下优化后的输出为:

Test duo output, non_reference tuple
Default constructor invoked
Parameter constructor invoked
Copy constructor invoked
Move Assignment operator invoked
100

在函数内部创建元组时调用复制构造函数似乎是不必要的。有什么办法可以去掉这个吗?我正在使用 MSVC 2012 编译器。

#include <iostream>
#include <tuple>

class A
{
public:
     int value;
     A() : value(-1)
     {
         std::cout << "Default constructor invoked" << std::endl;
     }

     explicit A(const int v) : value(v)
     {
         std::cout << "Parameter constructor invoked" << std::endl;
     }

     A(const A& rhs)
     {
         value = rhs.value;
         std::cout << "Copy constructor invoked" << std::endl;
     }

     A(const A&& rhs)
     {
         value = rhs.value;
         std::cout << "Move constructor invoked" << std::endl;
     }

     A& operator=(const A& rhs)
     {
         value = rhs.value;
         std::cout << "Assignment operator invoked" << std::endl;
         return *this;
     }

     A& operator=(const A&& rhs)
     {
         value = rhs.value;
         std::cout << "Move Assignment operator invoked" << std::endl;
         return *this;
     }
 };

 std::tuple<A, int> return_two_non_reference_tuple()
 {
     A tmp(100);

     return std::make_tuple(tmp, 99);
 }

 int main(int argc, char* argv[])
 {

      std::cout << "Test duo output, non_reference tuple" << std::endl;    
      A t3;
      int v1;
      std::tie(t3, v1) = return_two_non_reference_tuple();
      std::cout << t3.value << std::endl << std::endl;

      system("pause");
      return 0;
}

最佳答案

移动构造函数不会被自动调用,因为你正在调用

std::make_tuple(tmp, 99);

在这种情况下,tmp 是一个左值。您可以使用 std::move 将其转换为右值引用:

return std::make_tuple(std::move(tmp), 99);

这将指示编译器使用移动构造函数。

关于c++ - tuple/tie的返回值优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35935946/

相关文章:

c++ - 我需要什么类型的数据结构来链接到多个参数

c++ - cygwin下的ld无法找到存在的库

c++ - 具有不完全整数类型的结构和枚举

c++ - 如何为 C++ 元组编写折叠/求和函数?

c++ - 使用 SFINAE 让 `std::get` 玩得更好

c++ - 以后可以使用分配器构造 std::tuple 的元素吗?

c++ - Websocketpp 简单 HTTP 客户端

c++ - 如何在 C++ 中对数组进行排序和检查重复项?

c++ - 如何在 C++ 模板中使用比较表达式?

c++ - std::async 和 std::future 行为