C++自定义流操纵器,用于更改流上的下一个字符串

C++ custom stream manipulator that changes next string on stream

本文关键字:下一个 字符串 用于 自定义 操纵 C++      更新时间:2023-10-16

我想在这里做与接受的答案相同的事情,但我想使用 std::string,而不是使用 int: C++自定义流操纵器,用于更改流中的下一个项目

链接的答案显示了实现流格式化行为自定义的"正确"方法,但它要求格式化的输出操作是可扩展的 - 这可能是正确的,原因如下:

  • 因为您已经为自己的类型编写了operator<<并且可以完全控制行为,或者
  • 因为您正在打印标准库通过locale明确允许您控制的类型(例如,打印带有不同数字分隔符的整数(。

这些都不是std::string的情况。目的是std::string完全包含要打印的字符。这并非不可能,但我下面展示的解决方案是地狱般的笨拙,我真的不推荐它!string应已包含格式化的内容,不应由打印操作来更改该内容。

诀窍是我们想调用我们自己的operator<<,我们无法控制string的类型,所以我们控制流的类型。

#include <algorithm>
#include <iostream>
#include <string>
// Not really a stream, but works enough like one for our purposes
struct UpperStream {
    std::ostream& d_originalStream;
    UpperStream(std::ostream& originalStream)
      : d_originalStream(originalStream)
    {}
};
// Trick to turn a normal stream into our magic type
struct UpperHelper {} makeNextStringUpper;
UpperStream operator<<(std::ostream& os, UpperHelper)
{ return os; }
// Special printing for strings
std::ostream& operator<<(UpperStream const& us, std::string s)
{
    auto l = us.d_originalStream.getloc();
    std::transform(std::cbegin(s),
                   std::cend(s),
                   std::begin(s),
                   [=](char c){return std::toupper(c, l);});
    return us.d_originalStream << s;
}
// Default to normal printing for everything else, and then go back to normal
// stream behaviour
template <typename T>
std::ostream& operator<<(UpperStream const& us, T&& t)
{ return us.d_originalStream << t; }
int main()
{
    using namespace std::string_literals;
    std::cout << makeNextStringUpper << "Hello, World!n"s;
    std::cout << makeNextStringUpper << 123 << " Hello, World!n"s;
}

这将打印:

HELLO, WORLD!
123 Hello, World!

老实说,试图让它看起来像一个流操纵器的整个业务非常奇怪。在string本身上工作有什么问题?

std::string toUpper(std::string s)
{
    std::locale l;
    std::transform(std::cbegin(s), std::cend(s), std::begin(s),
                   [=](char c){return std::toupper(c, l);});
    return s;
}
int main()
{
    std::cout << toUpper("Hello, World!n"s);
}
相关文章: