使用 std::set 的范围
Using ranges with std::set
我想用几个数字范围初始化 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;
}
我写了 operator|
作为模板来处理 r 值和 l 值引用的各种组合。但是,operator|(&& x, && y)
版本仍然需要从 y
复制元素。可以避免吗?
range
函数在 运行 时执行。是否可以在编译时编写 运行 的 constexpr
版本?
有人看到任何其他可以优化的东西吗?
我应该使用完全不同的方法吗?
关键是:
a) 代码应该易于阅读。换句话说,它应该有点类似于数学表达式,例如:foo = [a, b) | [c, d)
b) 该程序将在嵌入式系统上 运行,因此代码占用空间和效率很重要(因此,没有 boost
)。
所有这些:
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
构造函数。
我想用几个数字范围初始化 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;
}
我写了
operator|
作为模板来处理 r 值和 l 值引用的各种组合。但是,operator|(&& x, && y)
版本仍然需要从y
复制元素。可以避免吗?range
函数在 运行 时执行。是否可以在编译时编写 运行 的constexpr
版本?有人看到任何其他可以优化的东西吗?
我应该使用完全不同的方法吗?
关键是:
a) 代码应该易于阅读。换句话说,它应该有点类似于数学表达式,例如:foo = [a, b) | [c, d)
b) 该程序将在嵌入式系统上 运行,因此代码占用空间和效率很重要(因此,没有 boost
)。
所有这些:
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
构造函数。