簡體   English   中英

使用“|” 帶有 std::views 的(管道)運算符無法編譯

[英]Using '|' (pipe) operator with std::views does not compile

在職業轉移之后,我正試圖跟上 std::views (以及一般的函數式編程)的速度。 我正在使用“|” (pipe) 運算符與向量上的 std::views::filter ,我很困惑為什么有些代碼結構可以編譯而其他代碼結構不能編譯。

此代碼創建一個由int向量組成的向量,然后按總和對其進行過濾。 我已經評論了讓我感到困惑的三個陳述,其中前兩個可以編譯,第三個沒有。

編譯錯誤是:

'|': no operator found which takes a left-hand operand of type 'std::vector<std::vector<int,std::allocator<int>>,std::allocator<std::vector<int,std::allocator<int>>>>' (or there is no acceptable conversion)  

(使用 MSVC19,使用/std:c++latest編譯)

我很困惑為什么這不能編譯,而(2)尤其如此?

#include <vector>
#include <numeric>
#include <ranges>

template<typename T>
auto buildMultiples(const std::vector<T>& base)
{
    std::vector<std::vector<T>> vRet;
    for(T n= 1; n <= 5; n++)
    {
        auto v = base;
        for (auto& m : v) m *= n;
        vRet.push_back(v);
    }
    return vRet;
}

template<typename T>
struct sumGreaterThan
{
    T _limit{ 0 };

    auto operator()(const std::vector<T>& v) {return std::accumulate(v.cbegin(), v.cend(), 0) > _limit;}
};
   
int main()
{
    using namespace std;
    vector<int> nums{1,2,3,4,5,6,7,8,9};

    auto mults = buildMultiples(nums);

    for (auto& m : buildMultiples(nums)) {} //1. Compiles

    sumGreaterThan sumFilter{ 10 };
    
    auto vecs = buildMultiples(nums);
    for (auto& m : vecs | views::filter(sumFilter)) {} //2. Compiles

    for (auto& m : buildMultiples(nums) | views::filter(sumFilter)) {} //3. Compilation Error!!
}

這是將左值vector傳遞給filter

vecs | views::filter(sumFilter)

而這是將右值vector傳遞給filter

buildMultiples(nums) | views::filter(sumFilter)

編譯器實現的當前規則是范圍適配器管道不能采用右值非視圖范圍(如vectorstring等)。 這是因為管道本身是非擁有的(視圖是非擁有的),並且作為防止懸空的安全機制而存在。

最近作為缺陷采用的新規則將允許這可能並且會導致filter擁有buildMultiples的結果(這是P2415 ),但編譯器還沒有實現它。 通過此更改,您的其他版本也將被編譯。

所以現在,你必須繼續這樣寫(就像你已經在做的那樣):

auto vecs = buildMultiples(nums);
for (auto& m : vecs | views::filter(sumFilter)) { ... }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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