2016-10-12 8 views
0

JavaにはPredicateクラスのC/C++構造/クラスがありますか?Java述語に相当する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++で同じプログラムを実装したいと思います。これを行うためのデフォルトの方法または外部ライブラリがありますか?

+1

'std :: function 'はどうですか? – immibis

答えて

4

C++は、Javaに非常に似ているように思われるラムダは、あなたが使っているの構築があります。

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

は、それが連鎖するには内蔵しておりませんが、考え方は同じです - インライン定義関数。 C++のロジック構造を使用して、lambdaを任意の構造に結合することができます。ラムダを使用することもできます。

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

簡体構文はauto lambdaName=[ <capture> ] (<params>) -> <ret> { body }

  • [<capture>]がラムダで撮影したJava final vars or effectively finalsのリストである、あなたがそれらをここに宣言するのではなくfinal
  • (<params>)としてそれらをマークするために取得するパラメータのリストですあなたのラムダの場合
  • ret - 返される型 - ラムダがコンパイラがr eturnedタイプ
  • { body } - あなたの場合syntax of C++11 lambda functions

    に自明

完全に吹き説明:C++はstd::bindと組み合わせて使用​​することができ、関数オブジェクトのテンプレートを持っている

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. 
1

述語についてまたはラムダ:

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は議論の余地があります。今後の標準では非推奨となる予定ではありませんので、代わりにラムダを使用することをおすすめします。

あなたはORSのあなたのチェーンのような文を作るためにBoost.FusionまたはBoost.Hanaを使用することができます。

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"); }) 

ライブ: fusionhana

また、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