根据函数参数选择 stdout 或 stderr

Choose stdout or stderr based on function argument

提问人:DEKKER 提问时间:5/1/2023 最后编辑:user4581301DEKKER 更新时间:5/2/2023 访问量:81

问:

我想创建一个模板来打印任何容器,其元素可以通过 std::cout 或任何其他流打印。

我希望能够知道它应该打印到哪个流中,因此我需要以某种方式将目标流作为参数传递?下面是我想出的代码。但是有几个问题我还没有弄清楚

如果我使用,那么我可以直接将 as 参数传递给,但问题是元素需要一段时间 std::cout 会处理类型转换,我想要容易得多?fprintf()streamfprintfchar *

template<template<typename...> typename C, typename E, typename S>
void my_printer(const C<E>& container,
                     S separator = ' ',
                     FILE *stream = stdout) {

  typename C<E>::size_type index = 0;
  typename C<E>::size_type lastIndex = container.size() - 1;

  for (const auto& element: container) {
    if (stream == stdout) {
      std::cout << element;
      if (index < lastIndex) {
        std::cout << separator;
      }
    } else if (stream == stderr) {
      std::cerr << element;
      if (index < lastIndex) {
        std::cerr << separator;
      }
    }
    index++;
  }
  
}
C++ 模板 IOSTREAM

评论

1赞 user4581301 5/1/2023
注意:如果你需要索引,只需一个简单的旧循环。为自己节省一些重复的代码和工作量:在顶部确定要向上的流一次,对流进行引用,然后在循环中使用引用。当有人递给你一个代表文件或套接字的时,你会怎么做?forstream
3赞 Ted Lyngmo 5/1/2023
你为什么要直接通过/而不是直接通过?stdoutstderrstd::coutstd::cerr
2赞 user4581301 5/1/2023
一旦你通过了其中一个标准流,整个问题就消失了。
1赞 Ted Lyngmo 5/1/2023
简化
1赞 DEKKER 5/1/2023
@user4581301使用索引循环,如果容器是列表,它就不起作用,那么我不能使用container[i]

答:

4赞 Sam Varshavchik 5/1/2023 #1

将参数更改为 :std::ostream &

template<template<typename...> typename C, typename E, typename S>
void my_printer(const C<E>& container,
                     S separator = ' ',
                     std::ostream &stream=std::cout) {

现在,如果您愿意,可以传递其中任何一个,或者显式传递,然后使用所有常规流格式化的操作。std::cerrstd::cout

1赞 vitaut 5/2/2023 #2

C++23 支持可以写入:std::printFILE

template <typename Container>
void my_printer(const Container& container,
                char separator = ' ',
                FILE *stream = stdout) {
  typename Container::size_type index = 0;
  typename Container::size_type lastIndex = container.size() - 1;

  for (const auto& element: container) {
    std::print(stream, "{}", element);
    if (index < lastIndex) {
      std::print(stream, "{}", separator);
    }
    index++;
  }
}

下面是一个使用 {fmt} 库的示例,基于:https://godbolt.org/z/M684WMfP6std::print

免责声明:我是 {fmt} 和 C++23 的作者std::print