使std :: set在比较元素时使用转换运算符

时间:2016-11-20 18:50:05

标签: c++ stl containers c++14 stdset

目前我使用std::map来保存键/值对:

#include <map>

using K = int;
struct P {}; // some useful payload

int main()
{
    std::map< K, P const > m;
    m.insert({1, {}});
    auto it = m.find(1);
    // access:
    it->first;
    it->second;
}

int这里仅举例说明。在我的用例中,mapped_type总是const

要访问有效负载P const,我必须使用名称不太透明的second。关于first也是如此。我想简单地命名为payload或其他方式。

为实现这一目标,我发明了以下方法:

#include <set>

using K = int;
struct P {};

struct A
{
    K key;
    P payload;
    operator K const & () const { return key; }
};

struct less
{
    using is_transparent = void;
    bool operator () (K const & l, K const & r) const
    {
        return l < r;
    }
};

int main()
{
    std::set< A, less > s;
    s.insert({1, {}});
    auto it = s.find(1);
    // access:
    it->key;
    it->payload;
}

在这里,我std::set每次都要使用转换运算符作为密钥类型。有用。但它被禁止接近吗?是否有未定义的行为

1 个答案:

答案 0 :(得分:3)

对我来说,它看起来技术上有效。

但它也属于“使你的代码变得如此不必要的复杂程度,以至于程序员在理解你正在做的事情之前必须看两次或三次,并且可以验证你正确地做了,基本上没有任何实际的好处“这是非常不好的。

事实上,你 - 代码自己的作者,不会少! - 觉得有必要来这里要求语言律师验证代码的正确性是一个很大的红旗,这可能值得。

如果您认为.first.second对您的代码描述不够充分,那么您可以通过以下方式解决当地问题:

auto& key     = it->first;
auto& payload = it->second;

甚至:

auto& payload = getPayload(it);

其中getPayload是一个适当的函数,它采用特定类型的迭代器。

这些方法具有相当明显的优点,并且不需要召集C ++最高法院的会议来首先检查它们。