代码之家  ›  专栏  ›  技术社区  ›  Alex

在C++中,如何从数组中提取成员并返回成员类型的数组?[关闭]

  •  -4
  • Alex  · 技术社区  · 7 年前
    namespace detail
    {
        template <typename T, typename U>
        Array<U> extract_(const Array<T>& array, std::function<U(const T&)> member)
        {
            Array<U> extracted;
    
            for (auto& item : array)
                extracted += member(item);
    
            return extracted;
        }
    }
    
    
    #define extract(container, member) detail::extract_(container, \
        std::function< typeof(typeof(container)::Type::element_type::member) (const typeof(container)::Type&)>( \
                       [&](const typeof(container)::Type& item){ return item->member; }))
    

    所以我想用这个算法从数组中提取成员。 Array<T>

    如果你对宏过敏,很抱歉,但这会使用户代码非常干净。

    我想做的是如果我有 Array<Size> sizeArray 与成员 double Array<Size>::Length auto lengths = extract(sizeArray, Length); 并且拥有 lengths 类型 Array<double> .

    我已经做了类似的事情

    namespace detail
    {
        template <typename T>
        Array<T> filter_(const Array<T>& array, std::function<bool(const T&)> condition)
        {
            Array<T> filtered;
    
            for (auto& item : array)
                if (condition(item)) filtered += item;
    
            return filtered;
        }
    }
    
    
    // this macro creates a capturing lambda, the item to check is called 'item'
    #define filter(container, condition) detail::filter_(container, \
        std::function<bool(const typeof(container)::Type&)>( \
                       [&](const typeof(container)::Type& item){ return condition; }))
    

    auto turnedOff = filter(objects, !item->IsTurnedOn); 它工作得很好,但是它返回的是相同的类型,所以这是一个更容易解决的任务。

    1 回复  |  直到 7 年前
        1
  •  4
  •   Alexander Kondratskiy    7 年前

    现在我们已经解决了这个问题,这里有一个有效的解决方案,它不涉及 std::function

    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    struct A
    {
        int x;
        double y;
    };
    
    template <typename T, typename U>
    auto extract(const std::vector<T>& vec, U T::* member)
    {
        std::vector<U> result;
        result.reserve(vec.size());
        std::transform(
            std::begin(vec), std::end(vec), std::back_inserter(result),
            [member] (const T& val) { return val.*member; }
        );
        return result;
    }
    
    int main() {
        std::vector<A> as{{10, 3.14}, {42, 1.618}};
        auto result = extract(as, &A::x);
        for (auto x : result)
            std::cout << x << std::endl;
        return 0;
    }
    

    https://ideone.com/ewieLc