c++如何创建流元组

C++ how to make tuple of ofstreams?

本文关键字:元组 创建 何创建 c++      更新时间:2023-10-16

我有三个std::ofstream对象,我把它们放在下面的函数中,并在main()中使用它们。当我编译它的时候,我得到了很多错误信息,有人能帮我吗?

#include<string>
#include<tuple>
#include<fstream>
#include<iostream>
std::tuple<std::ofstream, std::ofstream, std::ofstream>
set_ofstream_tuple() {
   std::ofstream out1("out1.txt", std::ofstream::out);
   out1 << "this is out1.txt" << std::endl;
   std::ofstream out2("out2.txt", std::ofstream::out);
   out2 << "this is out2.txt" << std::endl;
   std::ofstream out3("out3.txt", std::ofstream::out);
   out3 << "this is out3.txt" << std::endl;
   return std::make_tuple(out1, out2, out3);
}
int main() {
  std::ofstream out1, out2, out3;
  std::tie(out1, out2, out3) = set_ofstream_tuple();
  /// make use of there ofstreams more here
}

这一行:

return std::make_tuple<out1, out2, out3>;

是奇怪。你想干什么?:)

std::make_tuple是一个函数,它的参数组成一个元组:

return std::make_tuple(std::move(out1), std::move(out2), std::move(out3));

注意std::move,这些是必需的,因为你不能复制std::ofstream

问题是您在返回元组之前将不可复制的ofstream复制到元组中。

一种解决方案是在返回之前将of流移到元组中:

#include<string>
#include<tuple>
#include<fstream>
#include<iostream>
std::tuple<std::ofstream, std::ofstream, std::ofstream>
set_ofstream_tuple() 
{
   std::ofstream out1("out1.txt", std::ofstream::out);
   out1 << "this is out1.txt" << std::endl;
   std::ofstream out2("out2.txt", std::ofstream::out);
   out2 << "this is out2.txt" << std::endl;
   std::ofstream out3("out3.txt", std::ofstream::out);
   out3 << "this is out3.txt" << std::endl;
   return std::make_tuple(std::move(out1), std::move(out2), std::move(out3));
}
int main() {
  std::ofstream out1, out2, out3;
  std::tie(out1, out2, out3) = set_ofstream_tuple();
  /// make use of there ofstreams more here
}

proof: on godbolt

另一个解决方案是在创建时使用元组作为主存储:

#include<string>
#include<tuple>
#include<fstream>
#include<iostream>
std::tuple<std::ofstream, std::ofstream, std::ofstream>
set_ofstream_tuple() 
{
  auto streams = std::make_tuple(std::ofstream("out1.txt", std::ofstream::out),
                                 std::ofstream("out2.txt", std::ofstream::out),
                                 std::ofstream("out3.txt", std::ofstream::out));
  auto& out1 = std::get<0>(streams);
  auto& out2 = std::get<1>(streams);
  auto& out3 = std::get<2>(streams);
  out1 << "this is out1.txt" << std::endl;
  out2 << "this is out2.txt" << std::endl;
  out3 << "this is out3.txt" << std::endl;
  return streams;
}
int main() {
  std::ofstream out1, out2, out3;
  std::tie(out1, out2, out3) = set_ofstream_tuple();
  /// make use of there ofstreams more here
}

从c++17开始,我们将能够在即将到来的std::optional中避免空ofstream的冗余构造(这里使用std::experimental进行演示):

#include<string>
#include<tuple>
#include<fstream>
#include<iostream>
#include <experimental/optional>
std::tuple<std::ofstream, std::ofstream, std::ofstream>
set_ofstream_tuple() 
{
  auto streams = std::make_tuple(std::ofstream("out1.txt", std::ofstream::out),
                                 std::ofstream("out2.txt", std::ofstream::out),
                                 std::ofstream("out3.txt", std::ofstream::out));
  auto& out1 = std::get<0>(streams);
  auto& out2 = std::get<1>(streams);
  auto& out3 = std::get<2>(streams);
  out1 << "this is out1.txt" << std::endl;
  out2 << "this is out2.txt" << std::endl;
  out3 << "this is out3.txt" << std::endl;
  return streams;
}
int main() {
  std::experimental::optional<std::ofstream> out1, out2, out3;
  std::tie(out1, out2, out3) = set_ofstream_tuple();
  /// make use of there ofstreams more here
}