使用 C++14,我们可以将某些关联容器(如 std::set)的元素与存储在容器中的元素以外的其他类型进行比较。当比较器表示为一种类型时,它应该可以工作is_transparent
(参见例如std::set::find)。
假设我有一个字符串包装器,它对字符串执行一些检查(如果它的格式是有效的格式等等 - 不是很重要,但构造它足够重,我想避免它+它可以抛出异常)并且它是存储在 std::set 中以具有唯一值的容器。我应该如何为它写一个比较器?它应该看起来像下面的那个吗?我可以超载并使用 mysw::operator<()
来达到同样的效果吗?
class sw
{
public:
explicit sw(const std::string& s) : s_(s) { /* dragons be here */ }
const std::string& getString() const { return s_; }
bool operator<(const sw& other) const { return s_ < other.s_; }
private:
std::string s_;
};
struct Comparator
{
using is_transparent = std::true_type;
bool operator()(const sw& lhs, const std::string& rhs) const { return lhs.getString() < rhs; }
bool operator()(const std::string& lhs, const sw& rhs) const { return lhs < rhs.getString(); }
bool operator()(const sw& lhs, const sw& rhs) const { return lhs < rhs; }
};
int main()
{
std::set<sw, Comparator> swSet{ sw{"A"}, sw{"B"}, sw{"C"} };
std::cout << std::boolalpha << (swSet.find(std::string("A")) != swSet.end()) << std::endl;
}
我相信上面的代码应该能按预期工作,但是当我用 g++4.9 和 clang++3.6 对其进行测试时,两者都产生了关于缺少从string
to转换的错误,key_type
就好像Comparator::operator()
从未考虑过字符串重载一样。我错过了什么吗?