【问题标题】:What is the equivalent of boost::make_transform_iterator in the standard library?标准库中 boost::make_transform_iterator 的等价物是什么?
【发布时间】:2014-11-22 06:44:47
【问题描述】:

在处理 const 向量时,以下内容不起作用:

const std::vector<std::string> v;
v.push_back("test"); // error: v cannot be modified

相反,您必须在构造向量的同一行初始化向量。然而,即使有这个限制,boost::make_transform_iterator 也可以很容易地在将另一个向量的元素推入 v 之前对其进行操作。在此示例中,convert 是一个一元函数,它返回输入元素的转换版本:

auto beg = boost::make_transform_iterator(args.begin(), convert);
auto end = boost::make_transform_iterator(args.end(), convert);

const std::vector<const char*> vc { beg, end };

我查看了&lt;iterator&gt; 中可用的功能,但没有看到等效功能。它只是缺少它还是标准库没有它的原因?

【问题讨论】:

  • 如果有一个等价的,它很可能被称为std::make_transform_iterator。没有一个。 boost(和其他库)中有很多有用的东西不在标准库中。
  • 您要做什么并不明显。也许const std::vector&lt;std::string&gt; v={"hello","world"};
  • @Marc 不,我希望vc 避免被修改,因为它将由c_str() 填充,我已经阅读过,如果vc 调整大小或类似的东西,可能会导致指针无效.所以我试图在一行上初始化它,而不是在第二行上使用 std::transform。
  • 对不起,我仍然不知道你想要什么,我会把它留给其他人,但一个更好的例子可能会有所帮助:你的第一个块中的 test 和 @987654332 之间的关系是什么@ 在第二个?
  • @Marc 哦,我明白你的意思了。第一个示例只是显示 push_back 为 const 时的编译器错误。

标签: c++ c++11 boost iterator


【解决方案1】:

对于 C++11,总是有 lambda 就地初始化技巧

const auto vc = [&]{
    std::vector<const char*> tmp(v.size());
    std::transform(v.begin(), v.end(), tmp.begin(), convert);
    return tmp;
}();

const auto vc = [&]{
    std::vector<const char*> tmp;
    tmp.reserve(v.size());
    std::transform(v.begin(), v.end(), back_inserter(tmp), convert);
    return tmp;
}();

Live On Coliru

也就是说,我更喜欢 Boost Range 适配器:(也 Live On Coliru

const auto vc = boost::copy_range<std::vector<const char*> >(v | transformed(convert));
#include <algorithm>
#include <vector>
#include <iterator>
#include <string>

#include <functional>
#include <iostream>

int main()
{
    const std::vector</* const */ std::string> v { "test", "goodbye" };

    auto convert = std::mem_fn(&std::string::c_str);

    const auto vc = [&]{
        std::vector<const char*> tmp;
        tmp.reserve(v.size());
        std::transform(v.begin(), v.end(), back_inserter(tmp), convert);
        return tmp;
    }();

    for (auto cc : vc)
        std::cout << cc << "\n";
}

【讨论】:

  • 我相信以const auto vc = boost::copy_range... 开头的代码行与以#include 语句开头的代码块没有关系,并且这两者是分开的方法,你更喜欢前者。对吗?
  • @Alan 正确。 Boost Range 适配器让您基本上可以在一行中说同样的话
猜你喜欢
  • 2012-04-07
  • 2022-06-12
  • 2011-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-12
相关资源
最近更新 更多