我想创建一个函数,当给定vector
V时,会向V中的每个元素返回vector
reference_wrapper
个VR。
这很简单,但我还希望返回的向量复制反弹分配器,以防原始向量具有(可能是有状态的)自定义分配器。
我想出了下面的MVCE,它编写了godbolt。
#include <algorithm>
#include <string>
#include <vector>
#include <functional>
#include <type_traits>
// A class to make my nasty string unmoveable, and therefore expensive
// to sort
struct Nasty
{
Nasty(std::string s) : value_(std::move(s)) {}
Nasty(Nasty const&) = default;
Nasty& operator=(Nasty const&) = default;
auto value() const -> std::string const& {
return value_;
}
std::string value_;
};
// function object class to deduce types and perform the conversion
template<class V>
struct as_references_op
{
using vector_type = V;
using value_type = typename V::value_type;
static constexpr bool is_const = std::is_const<vector_type>::value;
using referred_type = std::conditional_t<is_const, std::add_const_t<value_type>, value_type>;
using allocator_type = typename V::allocator_type;
using a_traits = std::allocator_traits<allocator_type>;
using rebound_allocator = typename a_traits::template rebind_traits<referred_type>::allocator_type;
using result_type = std::vector<std::reference_wrapper<referred_type>, rebound_allocator>;
result_type operator()(V& v) const
{
auto result = result_type(v.begin(), v.end(), v.get_allocator());
return result;
}
};
// interface functions
template<class T, class A>
decltype(auto) as_references(std::vector<T, A> const& v)
{
auto op = as_references_op<std::vector<T, A> const>();
return op(v);
}
template<class T, class A>
decltype(auto) as_references(std::vector<T, A>& v)
{
auto op = as_references_op<std::vector<T, A>>();
return op(v);
}
// test
int main()
{
auto v = std::vector<Nasty> { Nasty("gah"), Nasty("bar"), Nasty("zoo"), Nasty("foo") };
auto sv = as_references(v);
auto by_dereferenced_value = [] (auto&& x, auto&& y) {
return x.get().value() < y.get().value();
};
std::sort(begin(sv), end(sv), by_dereferenced_value);
}