与模板成员函数的接口

Exa*_*gon 8 c++ oop templates functional-programming

我有兴趣为C++实现类似Java集合的环境.我知道这不是一个好主意等等,但我不想在以后使用它,但只是学习如何做一些先进的OOP.

我的问题是我想要一个collection<T>纯虚函数的基类模板.其中一个功能应该是map()a std::function<R(T)>.既然map()应该是虚拟的,我不知道我应该使用哪种返回类型.collection<R>因为成员函数模板不能是虚拟的,所以是不可能的.

如何map()collection<T>界面添加此类成员函数?

Bar*_*rry 7

如何mapcollection<T>界面添加此类成员函数?

简短的回答是:你没有.如果我有一些collection<int>,我想要map std::to_string它,我需要生产一个collection<std::string>.但vector_collection<int>需要产生一个vector_collection<std::string>和一个list_collection<int>需要产生一个list_collection<std::string>- 所以类型转换本身需要virtual化.但是你不能拥有virtual成员函数模板,所以没有办法表达这一点.

为了实现这一点,您必须为容器中放置的所有对象设置一个公共基本类型,然后才能拥有一个可以在其间进行转换的公共外观.也就是说,你真的只有collection<unique_ptr<Object>>这里map只是给你一个不同的collection<unique_ptr<Object>>,你只要mapcollection_facade<int, collection<unique_ptr<Object>>>进入collection_facade<std::string, collection<unique_ptr<Object>>>.通过大量工作并完全无视性能和类型安全性,您可以实现目标.


这是模板的优点.如果我想写map类似的东西vector,我可以写下:

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;
}
Run Code Online (Sandbox Code Playgroud)

要么:

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)
        );
}
Run Code Online (Sandbox Code Playgroud)

我必须分别map()为每个容器实施- 但无论如何我都必须这样做.而现在我没有放弃任何东西.此外,您经常编写与运行时容器无关的算法吗?