是否有可能/可以否定一个 boost 滤波的适配器,例如

std::vector<int> v = {1, 2, 3, 4, 5};
for(auto i : v | !filtered(is_even))
    std::cout << i << std::endl; // prints 1,3,5

而不是在lambda表达式中进行取反?

动机:我经常使用filter和lambda函数,但是当我多次使用过滤器时,通常会将其重构为自定义过滤器,例如
for(auto i : v | even) // note: my filters are more complex than even.
    std::cout << i << std::endl; // prints 2,4

现在,当我需要否定时,我正在为他们构建自定义过滤器,例如
for(auto i : v | not_even)
    std::cout << i << std::endl; // prints 1,2,3

但是我会发现更好的是能够取消过滤条件,例如
for(auto i : v | !even)
    std::cout << i << std::endl; // prints 1,2,3

最佳答案

这是我很快想到的:

#include <boost/range/adaptors.hpp>
#include <boost/functional.hpp>
#include <iostream>

namespace boost {
    namespace range_detail {

        template <typename T>
            auto operator!(filter_holder<T> const& f) -> decltype(adaptors::filtered(boost::not1(f.val)))
            {
                return adaptors::filtered(boost::not1(f.val));
            }
    }
}

int main()
{
    using namespace boost::adaptors;
    int const v[] = { 1, 2, 3, 4 };

    std::function<bool(int)> ll = [](int i){return 0 == (i%2);}; // WORKS
    // bool(*ll)(int) = [](int i){return 0 == (i%2);};           // WORKS
    // auto ll = [](int i){return 0 == (i%2);};                  // not yet

    auto even = filtered(ll);

    for (auto i : v | !even)
    {
        std::cout << i << '\n';
    }
}

上实时观看liveworkspace.org

请注意,它目前处理的形式为function pointerstd::function<...>的谓词,但尚未处理裸lambda(在GCC 4.7.2上)

关于c++ - 取反 boost 范围滤波适配器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14769418/

10-11 23:17