C++增强猫

C++ enhanced cat

假设我有一个从字符串到字符串的函数,例如:

string identity(string text) {
    return text;
}

如何将应用于输入的函数打印到输出,避免显式变量、输入和输出处理?类似于 Haskell.

中的 interact
int main() {
    std::interact(identity);
}

这确实会减少明显的代码,反而让算法和逻辑脱颖而出。

示例用法为:

$./enhanced_cat
Example
Example
$
template<class F>
struct interacter_t {
  F f;
  void operator()( std::istream& is = std::cin, std::ostream& os = std::cout ) {
    std::string in;
    while( getline( is, in ) ) {
      os << f(std::move(in)) << '\n';
    }
  }
};
template<class F>
interacter_t<std::decay_t<F>> interact( F&& f ) {
  return {std::forward<F>(f)};
}

然后:

int main() {
  auto io = interact(identity);
  std::cout << "Start:\n";
  io();
  std::cout << "End.\n";
}

我在交互对象的创建中添加了单独的调用。

你可以在一行中完成:

  std::cout << "Start:\n";
  interact(identity)();
  std::cout << "End.\n";

或者您可以将 interact 修改为 运行 和 interactor_t 而不是返回它。我个人喜欢这种区别:创建和执行是不同的东西。

live example.

此版本从输入流中读取所有内容,直到结束。读不到那很容易,只需替换 operator().

的正文即可

您可以推出自己的互动,如下所示。 (注意:可能不会按原样实际编译。)

void interact(string (*function)(string))
{
    string input;
    getline(cin, input);
    cout << function(input) << endl;
}

您可以使用 std::function 轻松自己编写这样的东西。示例:

#include <string>
#include <iostream>
#include <functional>

std::string identity(std::string const& text) {
    return text;
}

void interact(std::function<std::string(std::string const&)> f)
{
    std::string input;
    std::getline(std::cin, input);
    std::cout << f(input);
}

int main()
{
    interact(identity);
}

但这肯定不像惯用的 C++。尽管C++在一定程度上支持函数式编程,但它不是一种函数式编程语言,你不应该尝试用C++写Haskell。