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

在C++中,如何从数组中提取成员并返回成员类型的数组?,c++,arrays,templates,preprocessor,C++,Arrays,Templates,Preprocessor,我可以自动关闭=过滤器对象!项目->已打开;它工作得很好,但返回的类型相同,因此这是一项更容易解决的任务。不要使用这些宏。请看在上帝的份上 现在我们已经解决了这个问题,这里有一个可行的解决方案,它不涉及std::function的开销 什么是顺从?如果你对宏过敏,很抱歉,但这会让用户代码变得非常干净-不。@NeilButterworth:也许它的意思是说业务?我能应付我的顺从。那么问题是什么?另外,我建议使用decltype而不是typeof。既然您至少可以访问C++11,为什么不使用declt

我可以自动关闭=过滤器对象!项目->已打开;它工作得很好,但返回的类型相同,因此这是一项更容易解决的任务。

不要使用这些宏。请看在上帝的份上

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


什么是顺从?如果你对宏过敏,很抱歉,但这会让用户代码变得非常干净-不。@NeilButterworth:也许它的意思是说业务?我能应付我的顺从。那么问题是什么?另外,我建议使用decltype而不是typeof。既然您至少可以访问C++11,为什么不使用decltype呢?看起来您正试图创建一个范围版本,以反对这些无辜的宏?我的意思是,我知道当模块出现时,我会为此付出代价,因为我一半的东西会停止工作,我希望注射能帮助解决这个问题,但这对你们来说几乎是宗教信仰。。。我是一个单独的开发人员,没有其他人在看我的代码,我喜欢我称之为candy代码的东西,即不仅结构简单,而且视觉上简单的代码。all::标准装饰::对可读性没有任何帮助。由于这些宏,我的C++看起来像JavaScript。为什么不呢?所讨论的调用是extractas,&A::x vs detail::extract_container,std::function[&]const typeofcontainer::Type&item{return item->member;}。它只是暗示了某种程度上的语言误用。在某些情况下,您无法摆脱宏,但这不是其中之一。此外,您的解决方案意味着我必须在成员名称前面添加&A::,这正是我在此试图避免的。我之所以尝试将其封装在宏中,是为了自动化这些细微差别。auto-extractedArray=extractotherArray,MemberName;好的,只包装我的解决方案:定义EXTRACTcontainer、成员EXTRACTcontainer和decltypecontainer::value\u type::member。但现在要注意,若容器是某个复杂的表达式,那个么宏将爆炸。你可以继续修复这些缺陷,但它仍然是一个创可贴。这很公平。谢谢!
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; }))
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; }))
#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;
}