c++ - 在 C++ 中像 Perl 一样打印

标签 c++ printf

我可以在 C++ 中执行类似以下 Perl 代码的操作吗?
即复制 $string n 次 ?

printf ("%s\n",$string x 4);

最佳答案

虽然 C++ 没有运算符 x,但 C++ 是一种足够灵活的语言,您可以编写一个命名运算符 x,其工作是乘以字符串:

#include <string>
namespace strop {
  struct x_op {} x;
  struct x_lhs { std::string s; };
  x_lhs operator*( std::string s, x_op ) {
    return {std::move(s)};
  }
  std::string operator*( x_lhs&& lhs, std::size_t rhs ) {
    std::string retval;
    for( std::size_t i = 0; i < rhs; ++i ) {
      retval += lhs.s;
    }
    return retval;
  }
}

使用:

#include <iostream>
using strop::x;
int main () {
  std::string foo = "foo";
  std::cout << (foo *x* 5) << "\n"; // if you prefer std::cout
  printf("%s", (foo *x* 5).c_str()); // if you prefer printf
}

上面使用了一些琐碎的 C++11 功能,但不是本质上的。

C++03版本(效率较低):

#include <string>
namespace strop {
  struct x_op {} x;
  struct x_lhs { std::string s; x_lhs(std::string s_):s(s_) {} };
  x_lhs operator*( std::string s, x_op ) {
    return x_lhs(s);
  }
  std::string operator*( x_lhs lhs, std::size_t rhs ) {
    std::string retval;
    for( std::size_t i = 0; i < rhs; ++i ) {
      retval += lhs.s;
    }
    return retval;
  }
}

有趣的是,这适用于字符串文字:

  std::cout << "bar" *x* 3 << "\n";

因为它们隐含地变成了 std::string。如果您正在使用 printf,您仍然需要将其包装在 ().c_str() 中,否则您将面临未定义行为的风险(即使您从未提及 std::字符串).

您可以改为重载一些其他未命名的运算符,但是当您在重载中拥有两种类型时重载运算符是非常粗鲁的,并且可能导致并发症。

上述技术使用占位符类型 x_opx_lhs 来确保重载运算符仅在我们与命名运算符交互时才会生效。

选择 * 来包装我们命名的运算符 x 是因为该运算类似于乘法。

奖励:operator* 的疯狂版本,它使用 rhs 的位值来减少字符串争论的数量:

  std::string operator*( x_lhs lhs, std::size_t rhs ) {
    std::string retval;
    auto done = [rhs]( std::size_t n ) {
      return !(i < (sizeof(rhs)*8) && !(rhs &~std::size_t((1<<i)-1)));
    };
    for( int i = 0; true; ++i) {
      if (!done(i+1)) {
        if (rhs & (1 << i))
          retval += lhs;
        lhs += lhs;
        continue;
      } else {
        // high bit must be set, or we'd be done before, unless rhs was 0:
        if (rhs != 0)
          retval += std::move(lhs);
        break;
      }
    }
    return retval;
  }

尚未测试,但让我觉得很有趣。

关于c++ - 在 C++ 中像 Perl 一样打印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17071427/

相关文章:

c - 写入文件,但从桌面拉出文件时找不到数据

C++ 从多类型 csv 文件中读取

c++ - 随机数生成

c# - C++ std::regex 错误地验证整数

c - printf ("%*.*s",int,int,char *) 在c中是什么意思?

c++ - 没有空格的宏

c - 如何在 C 中打印出 fread() 的值

C:首先使用 printf 和 scanf 函数打印一个带有 0(08) 的数字

c++ - if、switch 和函数指针速度比较

c++ - 模板类 : No appropriate default constructor avaialable. 但是我的一些类不能有默认构造函数