如何为我的collection<T> 接口添加这样的map 成员函数?
简短的回答是:你不知道。如果我有一些collection<int> 并且我想在上面添加map std::to_string,我需要生成一个collection<std::string>。但是vector_collection<int> 需要生成vector_collection<std::string>,list_collection<int> 需要生成list_collection<std::string>——因此类型转换本身需要virtualized。但是你不能有virtual 成员函数模板,所以没有办法表达这一点。
为了使其工作,您必须为您放入容器中的所有对象拥有一个通用的基本类型,然后只需有一个可以在它们之间转换的通用外观。也就是说,你真的只有collection<unique_ptr<Object>>,而map 只是给你一个不同的collection<unique_ptr<Object>>,而你只是map 你的collection_facade<int, collection<unique_ptr<Object>>> 变成了collection_facade<std::string, collection<unique_ptr<Object>>>。通过大量的工作和完全无视性能和类型安全,你可以做到。
这就是模板的优势。如果我想为vector 之类的东西写map,我可以这样写:
template <class T, class A, class F, class R = std::result_of_t<F(T)>>
std::vector<R, A> map(std::vector<T, A> const& v, F f) {
std::vector<R, A> mapped;
mapped.reserve(v.size());
for (T const& elem : v) {
mapped.push_back(f(elem));
}
return mapped;
}
或:
template <class T, class A, class F, class R = std::result_of_t<F(T)>>
std::vector<R, A> map(std::vector<T, A> const& v, F f) {
return std::vector<R, A>(
boost::make_transform_iterator(v.begin(), f),
boost::make_transform_iterator(v.end(), f)
);
}
我必须为每个容器分别实现map() - 但无论如何我都必须这样做。现在我不会放弃任何东西。此外,您多久编写一次与运行时容器无关的算法?