【问题标题】:Why output of boost::adaptors::filtered has no member named size?为什么 boost::adaptors::filtered 的输出没有名为 size 的成员?
【发布时间】:2021-01-07 17:42:26
【问题描述】:

下面的虚拟程序编译并运行

#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <functional>
#include <utility>
#include <vector>

using boost::adaptors::filtered;
using boost::adaptors::transformed;
auto whatever = [](auto&& x){ return std::forward<decltype(x)>(x); };
auto whenever = [](auto&){ return true; };

int main() {
    std::vector<int> v{1,2,3};
    auto w1 = v | transformed(whatever);
    auto w2 = v | transformed(whatever) | filtered(whenever);
    w1.size();
    //w2.size();
}

取消注释注释行并尝试使用g++ -std=c++14 that_file.cpp 进行编译会导致此错误:

uffa.cpp: In function ‘int main()’:
uffa.cpp:17:8: error: ‘struct
boost::range_detail::filtered_range<<lambda(auto:2&)>, const
boost::range_detail::transformed_range<<lambda(auto:1&&)>, std::vector<int> >
>’ has no member named ‘size’
   17 |     w2.size();
      |        ^~~~

由于filteredtransformed 一样,接受一个范围并返回一个范围,我不明白为什么sizefiltered 的输出中不可用。

我知道transformedfiltered 是两个不同的数学函数(例如,前者假设它的输入是一个函子,而后者假设,如果我错了,请纠正我,它的输入是一个单子) ,但仍然......这里的输入是std::vector,那么询问filtered 的输出的size 有什么问题?

【问题讨论】:

    标签: c++ boost functional-programming c++14 monads


    【解决方案1】:

    转换范围时,大小不会改变。这意味着transform 可以知道大小将是多少,因为它与输入相同。

    当您过滤范围时,您可能会或可能不会从范围中删除元素。这是懒惰地完成的,所以在您通过过滤范围之前,您无法知道它将有多大。如果你做一个非惰性过滤器,你可以知道,但范围应该是惰性的。

    【讨论】:

    • 哦,原来是懒惰。谢谢,我会尽快接受的。
    • @Enlico 是的。如果您不实际评估过滤器,则无法知道结果大小。
    【解决方案2】:

    你可以使用boost::size:

    boost::size(w2)
    

    但在性能方面可能代价高昂。

    【讨论】:

    • 我接受了另一个答案,因为它解决了我遇到的错误的 why。然而,这个答案通过添加一个可能的解决方案 boost::size 增加了很多,并告诉我它强制评估范围。
    猜你喜欢
    • 2018-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-23
    • 1970-01-01
    • 2015-08-13
    相关资源
    最近更新 更多