C++ 初学者如何使用std::any_?
我想将一个值与其他几个值进行比较,并检查它是否至少与其中一个值匹配,我假设它是C++ 初学者如何使用std::any_?,c++,C++,我想将一个值与其他几个值进行比较,并检查它是否至少与其中一个值匹配,我假设它是 if (x = any_of(1, 2 ,3) // do something 但我在网上看到的例子是 bool any_of(InputIt first, InputIt last, UnaryPredicate) 这是什么意思 C++,如果这是一个愚蠢的问题,请道歉。< /P> < P>你可以创建一个函数,在这里你将X和其他两个数字进行比较,以检查它们是否相同,例如 bool anyof(int x,
if (x = any_of(1, 2 ,3)
// do something
但我在网上看到的例子是
bool any_of(InputIt first, InputIt last, UnaryPredicate)
这是什么意思
<新> C++,如果这是一个愚蠢的问题,请道歉。< /P> < P>你可以创建一个函数,在这里你将X和其他两个数字进行比较,以检查它们是否相同,例如
bool anyof(int x, int y, int z) {
if ((x == y) || (x == z))
return true;
}
然后在main中,您可以调用如下函数:
if (anyof(x, 1, 2))
cout << "Matches a number";
auto a = any_of(std::array {1, 2, 3, 4});
if (x == std::move(a)) // ...
if(任意(x,1,2))
cout这不是这个函数的用途
您的值必须已经存在于其他地方,它很可能是一个向量
对迭代器进行操作
C++中的迭代器是两个值,它们告诉你开始的位置,以及结束的范围。
大多数C++标准模板库集合,包括<>代码> STD::vector < /C> >,支持迭代器API,因此可以使用<代码> STD::YANYO<<代码> >
为了获得完整的示例,让我们检查向量是否包含42
,只需使用std::any_of
由于我们只想检查向量中的值是否存在,而不改变任何内容(std::any_of
不会修改集合),因此我们使用.cbegin()
和.cend()
返回常量向量的开始和结束,这对std::any_of
非常重要,因为它必须遍历整个向量,以检查是否至少有一个值与给定谓词匹配
最后一个参数必须是一元谓词,这意味着它是一个函数,接受单个参数,并返回给定参数是否符合某些条件
简单地说,std::any_of
用于检查集合中是否至少有一个值,该值具有您关心的属性
代码:
#包括
#包括
#包括
布尔值为42(整数值){
返回值==42;
}
int main(){
向量向量{
1, 2, 3,
//42//取消对此的注释
};
if(std::任意(vec.cbegin(),vec.cend(),is_42))的{
STD::CUT> P.>关于“C++中迭代器”的主题有很多文献和视频教程,你应该在那个方向做一些研究,因为它是C++中的一个基本概念。
简单总结一下:迭代器是指值集合(或范围)中的元素。此类集合的几个示例:
std::vector
是最常见的。它基本上是一个可调整大小的数组
std::list
是一个链接列表
std::array
是一个固定大小的数组,在C样式数组周围有一些很好的助手
int-myInt[12]
是一个C风格的整数数组。这个数组不应该再使用了
< P>从C++标准库中执行的算法,它对值集合(如<代码> STD::YANYO >)采用两个迭代器进行集合。第一个迭代器<代码>第一个< /代码>指向集合的开头,而<>代码> InputIt最后< /C> >指向集合的末尾(实际上是一个结束)。
一元谓词
是一个接受1个参数(一元)并返回bool(谓词)的函数
为了让std::任意
做你想做的事,你必须把你的值放在一个集合中,把x
放在一元谓词中
:
int x = 3;
std::vector values = {1, 2, 3};
if (std::any_of(values.begin(), values.end(), [x](int y) { return x == y; }))
// ...
本例中的一元谓词
是一个lambda函数
正如您所看到的,给出您的示例,这是一段非常详细的代码。但是,一旦您有了一个动态的要比较的值集合,或者您想要检查比相等更复杂的东西,这个算法就会变得更加有用
有趣的小实验
为了好玩,我制作了一个小代码片段,它实现了一个你想要的任何。它的代码相当多,也相当复杂(绝对不是初学者!),但它非常灵活,而且使用起来非常好。可以找到完整的代码
以下是您将如何使用它:
int main()
{
int x = 7;
std::vector dynamic_int_range = {1, 2, 3, 4, 5, 6, 7, 8};
if (x == any_of(1, 2, 3, 4, 5))
{
std::cout << "x is in the compile time collection!\n";
}
else if (x == any_of(dynamic_int_range))
{
std::cout << "x is in the run time collection!\n";
}
else
{
std::cout << "x is not in the collection :(\n";
}
std::string s = "abc";
std::vector<std::string> dynamic_string_range = {"xyz", "uvw", "rst", "opq"};
if (s == any_of("abc", "def", "ghi"))
{
std::cout << "s is in the compile time collection!\n";
}
else if (s == any_of(dynamic_string_range))
{
std::cout << "s is in the run time collection!\n";
}
else
{
std::cout << "s is not in the collection :(\n";
}
}
这不是一个愚蠢的问题,但正确回答它基本上是一本学习手册的两章。现在,你应该坚持使用逻辑OR运算符|
。你的函数有未定义的行为,因为它不会在所有执行路径上返回值。我还怀疑这个函数是否非常有用,因为它只与int一起工作代码>s,并且仅当有两个要比较时才使用。只需使用if((x==y)| |(x==z))
直接在需要的地方使用它似乎更直接。返回x==y | | x==z;
。虽然变量参数模板和折叠表达式更通用、更有用……有没有一种方法可以将其扩展到大量变量?@baguettio我做了一些更新,只是作为概念证明(这样你就能看到C++的力量了)。
namespace detail
{
template <typename ...Args>
struct ct_any_of_helper
{
std::tuple<Args...> values;
constexpr ct_any_of_helper(Args... values) : values(std::move(values)...) { }
template <typename T>
[[nodiscard]] friend constexpr bool operator==(T lhs, ct_any_of_helper const& rhs) noexcept
{
return std::apply([&](auto... vals) { return ((lhs == vals) || ...); }, rhs.values);
}
};
template <typename Container>
struct rt_any_of_helper
{
Container const& values;
constexpr rt_any_of_helper(Container const& values) : values(values) { }
template <typename T>
[[nodiscard]] friend constexpr bool operator==(T&& lhs, rt_any_of_helper&& rhs) noexcept
{
return std::any_of(cbegin(rhs.values), cend(rhs.values), [&](auto val)
{
return lhs == val;
});
}
};
template <typename T>
auto is_container(int) -> decltype(cbegin(std::declval<T>()) == cend(std::declval<T>()), std::true_type{});
template <typename T>
std::false_type is_container(...);
template <typename T>
constexpr bool is_container_v = decltype(is_container<T>(0))::value;
}
template <typename ...Args>
[[nodiscard]] constexpr auto any_of(Args&&... values)
{
using namespace detail;
if constexpr (sizeof...(Args) == 1 && is_container_v<std::tuple_element_t<0, std::tuple<Args...>>>)
return rt_any_of_helper(std::forward<Args>(values)...);
else
return ct_any_of_helper(std::forward<Args>(values)...);
}
auto a = any_of(std::array {1, 2, 3, 4});
if (x == std::move(a)) // ...