【问题标题】:C/C++ Equivalent of Java PredicateJava 谓词的 C/C++ 等价物
【发布时间】:2016-10-12 01:03:16
【问题描述】:

Java 中是否存在 Predicate 类的 C/C++ 等效结构/类?

具体来说,我有一个非常简单的 Java 代码,如下所示。

import java.util.function.Predicate;
public class JavaPredicates {
    public static void main(String[] args) {
        Predicate<String> i  = (s)-> s.equals("ABCD");
        Predicate<String> j  = (s)-> s.equals("EFGH");
        Predicate<String> k  = (s)-> s.equals("IJKL");
        Predicate<String> l  = (s)-> s.equals("MNOP");
        Predicate<String> m  = (s)-> s.equals("QRST");
        Predicate<String> n  = (s)-> s.equals("UVWYZ");

        System.out.println(i.or(j).or(k).or(l).or(m).or(n).test("ABCD"));
    }
}

我想用 C 或 C++ 实现相同的程序。是否有默认方式或外部库来执行此操作?

【问题讨论】:

  • std::function&lt;bool(string)&gt; 怎么样?

标签: java c++ c predicate predicates


【解决方案1】:

C++ 的 lambdas 看起来与您正在使用的 java 构造非常相似:

auto i = [](string const & s){return s == "ABCD";}

它没有内置链接,但概念相似——内联定义的函数。您可以使用 C++ 逻辑构造将 lambda 组合成您想要的任何构造——甚至使用 lambda 来完成。

auto final_check = [i,j,k,l,m,n](string const & s){return i(s) || j(s) || k(s).....};

【讨论】:

    【解决方案2】:

    简化语法为auto lambdaName=[ &lt;capture&gt; ] ( &lt;params&gt; ) -&gt; &lt;ret&gt; { body }

    • [&lt;capture&gt;] 是 lambda 捕获的 Java final vars or effectively finals 列表,您可以在此处声明它们而不是将它们标记为 final
    • (&lt;params&gt;) 是您的 lambda 参数列表
    • ret - 返回类型 - 如果您的 lambda 足够简单,编译器可以推断出返回类型,则可选
    • { body } - 不言而喻

    关于syntax of C++11 lambda functions的完整解释

    在你的情况下:

    auto i = [/* no capture */]
              (const std::string& s) // params
              // no ret type spec: simple enough, the compiler will deduce it
              { return s=="ABCD"; }
    ;
    // calling it is just as simple as
    std::string str="xyz";
    // no more i.test(str), you just call it as a function
    bool res0 = i(str); // will be false
    
    
    const char* charStr="mnp";
    bool res1 = i(charStr); // the compiler knows the charStr can be converted
                            // to std::string and will generate the code
                            // for this conversion.
    

    【讨论】:

      【解决方案3】:

      对于谓词,C++ 具有可与 std::bind 或 lambdas 结合使用的函数对象模板:

      auto i = [](auto const& v){ return v == "ABCD"; };
      auto j = [](auto const& v){ return v == "EFGH"; };
      auto k = bind(equal_to<>{}, "IJKL", placeholders::_1);
      auto l = bind(equal_to<>{}, "MNOP", placeholders::_1);
      

      bind 是有争议的,而且它在未来的标准中会被弃用并非不可能,因此通常建议使用 lambdas 代替它。

      您可以使用 Boost.Fusion 或 Boost.Hana 对您的 ors 链做出类似的声明:

      fusion::any(fusion::make_tuple(i, j, k, l), [](auto const& p){ return p("ABCD"); })
      hana::any_of(hana::make_tuple(i, j, k, l), [](auto const& p){ return p("ABCD"); })
      

      直播: fusion, hana

      或者,从 C++17 开始,您可以为此使用 fold expressions

      auto const any_of = [](char const* str, auto&&... vs) {
          return (... || vs(str));
      };
      
      any_of("ABCD", i, j, k, l)
      

      live demo

      【讨论】:

        猜你喜欢
        • 2010-11-19
        • 2010-10-24
        • 1970-01-01
        • 1970-01-01
        • 2018-05-17
        • 2010-11-03
        • 2014-08-29
        • 2011-07-21
        • 1970-01-01
        相关资源
        最近更新 更多