要检查向量是否v为空,我可以使用std::empty(v)or v.empty()。我查看了 cppreference 上的签名,但缺乏理解它们的知识。他们之间的关系如何?一个实现是否调用另一个实现?
我知道一个来自容器库,另一个来自迭代器库,但仅此而已。
eer*_*ika 27
std::vector::empty 和 std::empty 之间的区别
Container::empty成员函数和自由函数(模板)之间的区别与, , , , ,和,std::empty之间的区别相同。Container::sizestd::sizeContainer::datastd::dataContainer::beginstd::beginContainer::endstd::end
在所有这些情况下,对于任何标准容器,自由函数(例如std::empty)只需调用相应的成员函数。free 函数存在的目的是在容器(以及std::initializer_list)和数组之间提供统一的接口。数组不能像类模板那样拥有成员函数,因此它们对这些自由函数有专门的重载。
如果您正在使用模板化容器类型编写代码,那么您应该使用 free 函数,以便能够支持数组作为模板化类型。如果类型不是模板化的,那么除了可以方便地重构为模板(或只是普通数组)之外,选择使用成员函数或自由函数之间没有任何区别。
Nat*_*son 11
共有三个重载std::empty,但用于std::empty(v)向量的重载v是第一个:
template <class C>
constexpr auto empty(const C& c) -> decltype(c.empty()); // (since c++17, until c++20)
template <class C>
[[nodiscard]] constexpr auto empty(const C& c) -> decltype(c.empty());
(since C++20) // (since c++20)
Run Code Online (Sandbox Code Playgroud)
这种过载会产生以下影响:
- 回报
c.empty()
所以,std::empty(v)和v.empty()在这种情况下具有相同的效果。
std::empty返回调用的结果std::vector::empty。
std::empty对于以下场景很有用:容器可能会或可能不会empty()为提供成员函数的类型提供成员函数empty,std::empty提供默认实现,但对于不提供此函数的自定义类型,您可以empty在命名空间范围内提供一个函数以在模板中使用;由于依赖于参数的查找,与参数位于同一名称空间中的函数将用作后备:
namespace Custom
{
struct Container
{
bool m_empty;
};
constexpr bool empty(Container const& c) // custom implementation for our own type
{
return c.m_empty;
}
}
template<class T>
void PrintEmpty(char const* containerName, T&& container)
{
using namespace std;
std::cout << containerName << " is " << (empty(container) ? "empty" : "not empty") << '\n';
}
int main()
{
PrintEmpty("std::vector<int>()", std::vector<int>());
PrintEmpty("Container{}", Custom::Container{});
PrintEmpty("Container{ true }", Custom::Container{ true });
}
Run Code Online (Sandbox Code Playgroud)
对于语言律师来说,C++20 标准规定容器a的 a.empty()成员函数返回true当且仅当a.begin() == a.end()([container.requirements.general])。
非成员函数std::empty()在 [iterator.range] 中指定。重载constexpr auto empty(const C& c)\xe2\x80\x9c返回: c.empty() .\xe2\x80\x9d
因此,在标准中,非成员函数是根据成员函数指定的,而不是相反。一般来说,这并不意味着\xe2\x80\x99t意味着实现需要让非成员函数实际调用成员函数,只要它\xe2\x80\x9c的行为就像。\xe2\x80\x9d在这种情况下,该关系必须适用于 STL 容器类的任何允许的专门化,或者适用于自定义容器类,以便限制允许库的编写者执行的操作。
\n| 归档时间: |
|
| 查看次数: |
2438 次 |
| 最近记录: |