使用C++ 14,我们可以将一些关联容器(如std :: set)的元素与存储在容器中的其他类型进行比较.当比较器is_transparent表示为一种类型时,它应该起作用(参见例如std :: set :: find).
假设我有一个字符串包装器,它对字符串执行一些检查(如果它的格式是有效格式等等 - 不是很重要,但构造它足够重,我想避免它+它可以抛出异常)并且它是存储在std :: set中以具有唯一值的容器.我该如何为它写一个比较器?它应该像下面那样吗?我能超载并使用我sw::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;
}
Run Code Online (Sandbox Code Playgroud)
我相信,上面的代码应该工作正常,但是当我使用g ++ 4.9和铛++ 3.6进行了测试,都取得了有关从失踪转换错误string,以key_type仿佛串过载Comparator::operator()从未考虑.我错过了什么吗?
operator<是的,该代码是正确的,但是重载以允许比较您的类型std::string然后仅使用已经“透明”的std::less<>(即)会更简单std::less<void>。
inline bool operator<(const sw& lhs, const std::string& rhs) { return lhs.getString() < rhs; }
inline bool operator<(const std::string& lhs, const sw& rhs) { return lhs < rhs.getString(); }
std::set<sw, std::less<>> swSet{ sw{"A"}, sw{"B"}, sw{"C"} };
Run Code Online (Sandbox Code Playgroud)
另外,可能值得注意的是,您定义什么并不重要is_transparent,其中任何一个都会与您的定义具有相同的效果:
using is_transparent = std::false_type;
using is_transparent = void;
Run Code Online (Sandbox Code Playgroud)