使用带有std :: set的范围

时间:2015-01-21 03:00:10

标签: c++ c++11

我想用几个数字范围初始化std::set。我想有效地进行(最小化复制),而不使用boost,并且最终用户(我自己:)目前具有良好的代码可读性。)

以下是我到目前为止所提出的建议,但我可以看到一些效率低下的问题,并希望了解是否有可能以及如何解决这些问题。具体问题在代码下面。

#include <iostream>
#include <set>

typedef std::set<int> codes;

template<typename T>
inline codes operator|(codes&& x, T&& y)
{
    codes c(std::move(x));
    c.insert(y.begin(), y.end());
    return c;
}

template<typename T>
inline codes operator|(const codes& x, T&& y)
{
    codes c(std::forward<T>(y));
    c.insert(x.begin(), x.end());
    return c;
}

inline codes range(int min, int max)
{
    codes c;
    for(int ri = min; ri < max; ++ri) c.insert(ri);
    return c;
}

void print_set(const std::string& name, const codes& set)
{
    std::cout << name << " = ";
    for(int ri: set) std::cout << ri << ' ';
    std::cout << std::endl;
}

int main()
{
    codes r1 = { 1, 2, 3 };
    codes r2 = range(5, 10);
    codes r3 = r1 | r2;
    codes r4 = r2 | range(15, 20);
    codes r5 = range(1, 10) | r1;
    codes r6 = range(1, 5) | range(10, 15);

    print_set("r1", r1);
    print_set("r2", r2);
    print_set("r3", r3);
    print_set("r4", r4);
    print_set("r5", r5);
    print_set("r6", r6);

    return 0;
}
  1. 我写了operator|作为模板来处理r值和l值引用的各种组合。但是,operator|(&& x, && y)版本仍需要复制y中的元素。有可能避免它吗?

  2. range函数在运行时执行。是否可以编写在编译时运行的constexpr版本?

  3. 任何人都可以看到其他可以优化的内容吗?

  4. 我应该使用完全不同的方法吗?

  5. 关键是:

    a)代码应易于阅读。换句话说,它应该有点类似于数学表达式,例如:foo = [a, b) | [c, d)

    b)程序将在嵌入式系统上运行,因此代码占用空间和效率很重要(因此,没有boost)。

1 个答案:

答案 0 :(得分:4)

所有这一切:

template<typename T>
inline codes operator|(codes&& x, T&& y)
{
    codes c(std::move(x));
    c.insert(y.begin(), y.end());
    return c;
}

template<typename T>
inline codes operator|(const codes& x, T&& y)
{
    codes c(std::forward<T>(y));
    c.insert(x.begin(), x.end());
    return c;
}

可以写成:

template<typename T>
inline codes operator|(codes x, T&& y)
{
    using std::begin;
    using std::end;
    x.insert( begin(y), end(y) );
    return x;
}

按值传递codes x将为左值和右值实现正确且已经过良好测试的std::set构造函数。