2016-10-12 6 views
0

Existe-t-il une structure/classe équivalente C/C++ de classe Predicate en Java?Equivalent C/C++ de Java Predicate

Plus précisément, j'ai un code Java très simple comme indiqué ci-dessous.

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

Je veux implémenter le même programme en C ou C++. Existe-t-il un moyen par défaut ou une bibliothèque externe pour cela?

+1

Que diriez-vous de 'std :: function '? – immibis

Répondre

4

C++ a lambdas qui semblent être tout à fait semblable à la java construire que vous utilisez:

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

Il n'a pas construit en enchaînant, mais le concept est similaire - une fonction définie en ligne- . Vous pouvez utiliser les constructions logiques C++ pour combiner les lambdas dans n'importe quelle construction que vous souhaitez - même utiliser un lambda pour le faire.

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

Syntaxe simplifiée est auto lambdaName=[ <capture> ] (<params>) -> <ret> { body }

  • [<capture>] est la liste de Java final vars or effectively finals capturé par le lambda, vous obtenez de les déclarer ici plutôt que de les marquer comme final
  • (<params>) la liste des paramètres pour votre lambda
  • ret - type retourné - facultatif si votre lambda est assez simple pour que le compilateur en déduise Type eturned
  • { body } - de soi

explication entièrement soufflée sur syntax of C++11 lambda functions

Dans votre cas:

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

Pour prédicats C++ a des modèles d'objet fonction qui pourrait être utilisé avec conjonction avec std::bind ou 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); 

bindbind est controversé et il n'est pas impossible qu'il sera prévu pour la dépréciation dans les normes futures, il est donc souvent conseillé d'utiliser lambdas à sa place.

Vous pouvez utiliser Boost.Fusion ou Boost.Hana pour faire une déclaration similaire à votre chaîne de 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"); }) 

en direct: fusion, hana

Alternativement, puisque C++ 17 vous pouvez utiliser fold expressions pour cela:

auto const any_of = [](char const* str, auto&&... vs) { 
    return (... || vs(str)); 
}; 

any_of("ABCD", i, j, k, l) 

live demo