![](/img/trans.png)
[英]Why does this Boost TCP socket work in one method and not in another?
[英]Does boost::combine() work with output of a method?
在下面的测试用例中,我使用boost :: combine来迭代函数getPoints()
输出。
预期产出
我希望(1,2,3)打印6次; 因为我有效拉链两个列表 -
([point,point,point],[point,point,point])。
实际产出
输出对我来说是令人惊讶的,也是错误的。 前两行是关闭表明内存损坏?
(0, 0, 3) // <-- wrong!
(52246144, 0, 3) // <-- wrong! memory corruption?
(1, 2, 3)
(1, 2, 3)
(1, 2, 3)
(1, 2, 3)
这也可以在这里在线验证, http://cpp.sh/622h4 。
这是一个错误吗?
代码如下 -
#include <iostream>
#include <vector>
#include <boost/range/combine.hpp>
struct Point {
int x, y, z;
};
const std::vector<Point> getPoints() {
// There is only one Point in the entire code, which is (1, 2, 3).
const Point point = {1, 2, 3};
// Return a vectore of 3 copies of the point (1, 2, 3).
return {point, point, point};
}
int main() {
// Zip over two copies of 3-tuples of {1, 2, 3}.
for (const auto& zipped : boost::combine(getPoints(), getPoints())) {
auto p1 = zipped.get<0>();
auto p2 = zipped.get<1>();
// Expected output is (1, 2, 3), six times.
std::cout << "(" << p1.x << ", " << p1.y << ", " << p1.z << ")" << std::endl;
std::cout << "(" << p2.x << ", " << p2.y << ", " << p2.z << ")" << std::endl;
}
return 0;
}
当您访问悬空引用时,此处有未定义的行为。 这可以修复
const auto points1 = getPoints();
const auto points2 = getPoints();
for (const auto& zipped : boost::combine(points1, points2)) {
// ...
}
在处理范围库时,Rvalue引用总是有问题的。 显然,像boost::combine
这样的范围算法不会复制参数。 它创建了一个新的代理范围对象,这使得无法延长传入的临时范围的生命周期。
相反, for(const auto& item: getPoints()) {...}
的基于范围的for循环扩展为
{
auto && __range = getPoints();
for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin) {
range_declaration = *__begin;
loop_statement
}
}
getPoints()
的生命周期通过将其绑定到右值引用来扩展。 想象一下功能模板combine
为
template<class Rng>
auto combine(Rng&& rng) {
auto && == range; // Nice try but doesn't help
// ...
return someProxyRange;
}
此函数模板无法延长rng
的生命周期,因为它的行为与rng
不同,后者来自客户端。 在基于循环的范围中,这是不同的。 临时(例如getPoints()
)和转发引用auto&& __range
的范围在同一范围内,因此可以延长生命周期。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.