在 C++ 中,如何从数组中提取成员并 return 成员类型的数组?
In C++ how can I extract members from an array and return an array of the member's type?
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
是类型 [=18] =].
我已经用
做了类似的事情
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);
并且效果非常好,但它返回的类型相同,因此解决起来更容易。
不要使用那些宏。请。为了上帝的爱。
现在我们已经解决了这个问题,这是一个可行的解决方案,它不涉及 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;
}
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
是类型 [=18] =].
我已经用
做了类似的事情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);
并且效果非常好,但它返回的类型相同,因此解决起来更容易。
不要使用那些宏。请。为了上帝的爱。
现在我们已经解决了这个问题,这是一个可行的解决方案,它不涉及 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;
}