正如我之前所说,我之前已经完成了所有操作,但它无法与std::basic_string<T,U>
(以及std::set
由于使用 的朋友std::back_inserter
)一起工作,因为它只会将其重新绑定到std::basic_string<stuff,U>
而不是底层容器。但是请注意,将其扩展为适用于std::basic_string<T, U>
.
我做的第一件事是定义一个function_traits
和一个Rebind
元函数,它将类型重新绑定Container<T>
到Container<U>
whereU
是传递函数的结果类型并且T
是原始类型。结果类型是通过function_traits
元函数找到的。您可以在下面看到完整的工作代码:
#include <type_traits>
#include <algorithm>
/* Helpers */
template<typename T>
using Type = typename T::type;
template<typename T>
using Unqualified = Type<std::remove_reference<Type<std::remove_cv<T>>>>;
template<typename Specialization, typename Target>
struct rebind {};
/* Sensible default: assume first parameter is for the target */
template<template<typename...> class Cont, typename T, typename... Ts, typename Target>
struct rebind<Cont<T, Ts...>, Target> {
using type = Cont<Target, Ts...>;
};
/* Special-case */
template<typename Old, std::size_t N, typename Target>
struct rebind<std::array<Old, N>, Target> {
using type = std::array<Target, N>;
};
template<typename Specialization, typename Target>
using Rebind = Type<rebind<Specialization, Target>>;
#include <tuple>
template<typename T>
struct function_traits : public function_traits<decltype(&T::operator())> {};
template<typename T, typename R, typename... Args>
struct function_traits<R(T::*)(Args...) const> {
static constexpr size_t args = sizeof...(Args);
using result_type = R;
template<size_t i>
struct arg {
using type = typename std::tuple_element<i,std::tuple<Args...>>::type;
};
};
template<typename T>
using Resultant = typename function_traits<T>::result_type;
template<class Cont, typename Map>
auto map(const Cont& cont, Map&& mapped) -> Rebind<Cont, Resultant<Unqualified<Map>>> {
Rebind<Cont, Resultant<Unqualified<Map>>> result;
auto result_iterator = std::back_inserter(result);
for(const auto& elem : cont) {
*result_iterator = mapped(elem);
}
return result;
}
#include <iostream>
int main() {
auto i = map(std::vector<int>{1,2,3,4,5,6}, [](int x) { return x % 2 == 0; });
for(auto&& j : i) {
std::cout << j << ' ';
}
}
输出:
0 1 0 1 0 1
Coliru 上的实时版本