C/C++ 等价于 Java 谓词
C/C++ Equivalent of Java Predicate
在Java中是否有谓词class的C/C++等价物structure/class?
具体来说,我有一个非常简单的 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++ 实现相同的程序。是否有默认方式或外部库来执行此操作?
C++ 的 lambda 看起来与您正在使用的 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).....};
简化语法为 auto lambdaName=[ <capture> ] ( <params> ) -> <ret> { body }
[<capture>]
是 lambda 捕获的 Java final vars or effectively finals
的列表,你可以在这里声明它们而不是将它们标记为 final
(<params>)
是您的 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.
对于谓词,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
是有争议的,它在未来的标准中被弃用也并非不可能,因此通常建议使用 lambda 代替它。
您可以使用 Boost.Fusion 或 Boost.Hana 对您的 or 链做出类似的声明:
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"); })
或者,从 C++17 开始,您可以为此使用 fold expressions:
auto const any_of = [](char const* str, auto&&... vs) {
return (... || vs(str));
};
any_of("ABCD", i, j, k, l)
在Java中是否有谓词class的C/C++等价物structure/class?
具体来说,我有一个非常简单的 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++ 实现相同的程序。是否有默认方式或外部库来执行此操作?
C++ 的 lambda 看起来与您正在使用的 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).....};
简化语法为 auto lambdaName=[ <capture> ] ( <params> ) -> <ret> { body }
[<capture>]
是 lambda 捕获的 Javafinal vars or effectively finals
的列表,你可以在这里声明它们而不是将它们标记为final
(<params>)
是您的 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.
对于谓词,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
是有争议的,它在未来的标准中被弃用也并非不可能,因此通常建议使用 lambda 代替它。
您可以使用 Boost.Fusion 或 Boost.Hana 对您的 or 链做出类似的声明:
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"); })
或者,从 C++17 开始,您可以为此使用 fold expressions:
auto const any_of = [](char const* str, auto&&... vs) {
return (... || vs(str));
};
any_of("ABCD", i, j, k, l)