为什么boost::adaptors::filtered的输出没有名为size的成员?

以下虚拟程序编译并运行

#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();
      |        ^~~~

由于filtered,就像transformed,需要一个范围并返回一个范围,我不明白为什么sizefiltered的输出中不可用。

我知道,transformedfiltered是两个不同的数学函数(如前者假定它的输入是一个仿函数,而后者承担,纠正我,如果我错了,它的输入是一个单子),但仍...在这里输入是std::vector这样有什么错询问size的输出filtered

回答

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

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

  • @Enlico Yep. If you don't actually evaluate the filter you can't know the resulting size.

以上是为什么boost::adaptors::filtered的输出没有名为size的成员?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>