点击上方【蓝字】关注博主
“ C++14 引入了一个强大的特性,允许我们在关联容器中使用不同类型的键进行搜索,这对于使用自定义比较函数的 set 尤其有用。这项功能通过引入 is_transparent 类型别名来实现,它允许比较函数对象支持透明比较,进而使得 find 方法能够接受任何能够与集合元素进行比较的值。本文将深入探讨 is_transparent 的作用机制,并通过示例说明如何利用这一特性简化代码设计,提升开发效率。”
背景
C++14 引入了一项引人注目的功能,为关联容器弥补了某些案例中长久以来的不足之处:即允许使用在语义上被视为键,但在技术上并非真正键的值对关联容器进行搜索。这意味着可以在关联容器中使用与存储元素不同类型的值进行查找。例如,可以使用员工的 ID 在一组包含 Employee
对象的集合中进行搜索,即使该 ID 并不构成 Employee
对象的组成部分。
初衷
class Employee
{
public:
explicit Employee(int id, std::string const& name) : id_(id), name_(name) {}
int getId() const { return id_; }
std::string getName() const { return name_; }
private:
int id_;
std::string name_;
};
struct CompareId
{
bool operator()(Employee const& employee1, Employee const& employee2) const {
return employee1.getId() < employee2.getId();
}
};
std::set<Employee, CompareId> employees;
struct CompareId
{
bool operator()(Employee const& employee1, Employee const& employee2) const
{
return employee1.getId() < employee2.getId();
}
bool operator()(int id, Employee const& employee) const
{
return id < employee.getId();
}
bool operator()(Employee const& employee, int id) const
{
return employee.getId() < id;
}
};
std::set<Employee, CompareId> employees = { Employee(1, "John"), Employee(2, "Bill") };
std::cout << employees.find(1)->getName() << '\
';
iterator find( const Key& key );
通过向
Employee
类添加一个仅接收引用的构造函数,以构造不完整的“空”员工,仅为进行比较。通过使用
std::map<int, Employee>
,从而打破了整个设计,导致 ID 的重复存储。通过将
Employee
类中的 ID 移除,并将其作为键用于std::map<int, Employee>
中,进而破坏有意义的设计以避免 ID 的重复。
就在绝望的修改整个程序时,C++14 的到来及时为其提供了救赎。
is_transparent
struct CompareId
{
using is_transparent = void; // 可使用 void,也可选择 int 或 struct CanSearchOnId;
bool operator()(Employee const& employee1, Employee const& employee2) const
{
return employee1.getId() < employee2.getId();
}
bool operator()(int id, Employee const& employee) const
{
return id < employee.getId();
}
bool operator()(Employee const& employee, int id) const
{
return employee.getId() < id;
}
};
std::set<Employee, CompareId> employees = { Employee(1, "Lion"), Employee(2, "Long") };
std::cout << employees.find(1)->getName() << '\
';
这一功能以比通用 lambda 表达式等新特性更为低调但仍然极具价值的方式融入标准库,为我们在使用关联容器时提供了一个更优雅且更简洁的方法,以便利用不同类型的键进行搜索。
总结
is_transparent 是 C++14 中一项强大的创新,允许我们以与集合元素类型不同的值进行搜索。这一功能简化了代码设计,提升了开发效率,为我们在关联容器上执行操作提供了更大的灵活性。
公众号: Lion 莱恩呀
微信号: 关注获取
扫码关注 了解更多内容
点个 在看 你最好看