可以提升:algorithm :: join()concat容器的浮点数?

时间:2013-06-06 14:11:20

标签: c++ string boost stl adapter

Boost join可用于连接由分隔符字符串分隔的字符串容器,如下例所示:A good example for boost::algorithm::join

我的STL技能很弱。我想知道是否有任何方法可以为一个数字容器(浮点数,双打数,整数)使用相同的函数?看起来应该有一个或两个班轮来适应其他类型。

还有stl的复制功能,这里有一个很好的例子: How to print out the contents of a vector?

但我不喜欢它如何在每个元素之后添加分隔符字符串。我想使用boost。

2 个答案:

答案 0 :(得分:23)

当然,您可以将boost::algorithm::joinboost::adaptors::transformed合并,将双打转换为字符串,然后将它们连接在一起。

#include <iostream>
#include <vector>
#include <string>

#include <boost/algorithm/string/join.hpp>
#include <boost/range/adaptor/transformed.hpp>

int main()
{
    using boost::adaptors::transformed;
    using boost::algorithm::join;

    std::vector<double> v{1.1, 2.2, 3.3, 4.4};

    std::cout 
      << join( v | 
               transformed( static_cast<std::string(*)(double)>(std::to_string) ), 
               ", " );
}

输出:

  

1.100000,2.200000,33000,4.400000


你也可以使用lambda来避免丑陋的演员

join(v | transformed([](double d) { return std::to_string(d); }), ", ")

答案 1 :(得分:1)

  

我的STL技能很弱。我想知道是否有相同的功能用于数字容器(浮点数,双打数,整数)?看起来似乎应该有一个或两个衬里来适应其他类型。

std::accumulate允许使用二进制函数对任何(输入)迭代器范围进行折叠,该函数可以为“累加器”和下一个项目采用不同的类型。在您的情况下:一个函数采用std::stringdouble(或其他)连接给定std::string的结果std::to_string第二个参数。

template<typename Container>
std::string contents_as_string(Container const & c,
                               std::string const & separator) {
  if (c.size() == 0) return "";
  auto fold_operation = [&separator] (std::string const & accum,
                                      auto const & item) {
    return accum + separator + std::to_string(item);};
  return std::accumulate(std::next(std::begin(c)), std::end(c),
                         std::to_string(*std::begin(c)), fold_operation);
}

如您所见,这完全独立于容器的值类型。只要你能把它传递给std::to_string,你就会很好。 实际上,上面的代码是the example presented for std::accumulate的略微变化。

Demo of above function

int main() {
  std::vector<double> v(4);
  std::iota(std::begin(v), std::end(v), 0.1);
  std::cout << contents_as_string(v, ", ") << std::endl;

  std::vector<int> w(5);
  std::iota(std::begin(w), std::end(w), 1);
  std::cout << contents_as_string(w, " x ") << " = "
    << std::accumulate(std::begin(w), std::end(w), 1, std::multiplies<int>{})
    << std::endl;
}
  

0.100000,1.10000,2.100000,310000
  1 x 2 x 3 x 4 x 5 = 120