簡體   English   中英

boost :: combine()是否與方法的輸出一起工作?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM