代码之家  ›  专栏  ›  技术社区  ›  Caridorc

C++增强型cat

  •  0
  • Caridorc  · 技术社区  · 10 年前

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

    string identity(string text) {
        return text;
    }
    

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

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

    这将真正减少明显的代码,并让算法和逻辑脱颖而出。

    示例用法如下:

    $./enhanced_cat
    Example
    Example
    $
    
    3 回复  |  直到 10 年前
        1
  •  1
  •   Christian Hackl    10 年前

    你可以自己用 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。

        2
  •  1
  •   Yakk - Adam Nevraumont    10 年前
    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";
    }
    

    我将单独的调用添加到interactor对象的创建中。

    您可以在一行中完成:

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

    或者您可以修改 interact 运行 interactor_t 而不是将其返回。我个人喜欢这种区别:创造和执行是不同的事情。

    live example .

    此版本读取输入流中的所有内容,直到其结束。阅读量低于此值很容易,只需更换 operator() .

        3
  •  1
  •   Ethan Fine    10 年前

    你可以进行自己的互动,如下所示。(注意:可能不会按原样编译。)

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