我希望能够写出类似的东西

char f(char);
vector<char> bar;
vector<char> foo = map(f, bar);

transform 函数看起来很相似,但它不会自动生成结果集合的大小。

有帮助吗?

解决方案

您可以使用 std::back_inserter<iterator>, ,尽管提供前面的大小更有效。例如:

string str = "hello world!", result;
transform(str.begin(), str.end(), back_inserter(result), ::toupper);
// result == "HELLO WORLD!"

其他提示

这个问题是在 C++11 标准生效之前提出的……如今我们有 std::transform() 作为(丑陋的)函数式编程“地图”的等价物。使用方法如下:

auto f(char) -> char; // or if you like: char f(char)
vector<char> bar;
vector<char> foo;
// ... initialize bar somehow ...
std::transform(bar.begin(), bar.end(), std::back_inserter(foo), f);

为了完成这项工作,您需要以下观察结果:

  1. 为了使作业有效, map 功能应该 不是 做工作。相反,它应该将其参数保存在临时对象中(就您而言,这将是 class map::result<char(*)(char), vector<char> >)
  2. map::result 临时应该有一个 template <typename T> operator T 转换。
  3. 当。。。的时候 map::result 被分配给 std::vector<char>, ,这种转换是唯一可行的。
  4. 在转换操作员中 class map::result<char(*)(char), vector<char> >::operator vector<char> 您具有输入和返回类型以及映射功能。此时,您可以有效地转换输入。

<edit>

代码

template<typename CONT, typename FUNC>
class mapresult {
    CONT const& in;
    FUNC f;
public:
    template<typename RESULT> RESULT to() const
    {
        RESULT out;
        for (auto const& e : in) { out.push_back(f(e)); }
        return out;
    }
    template<typename RESULT> operator RESULT() const
    {
        return this->to<RESULT>();
    }
    mapresult(CONT const& in, FUNC f) : in(in), f(std::move(f)) { }
};

template<typename CONT, typename FUNC>
auto map(CONT const& in, FUNC f) -> mapresult<CONT, FUNC>
{
    return mapresult<CONT, FUNC>(in, f);
}

这样使用:

using namespace std;
char foo(char c) { return c | ('A' ^ 'a'); }
std::string in = "Test";

int main(int argc, char* argv[])
{
    string out = map(in, &foo);
    cout << out << endl;

    char replace = 'e';
    cout << map(in, [replace](char c){return c == replace ? '?' : c; }).to<string>();
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top