C ++ - 将向量<custom_class>的属性连接到字符串</custom_class>中

时间:2014-07-14 20:20:51

标签: c++

我有一个std::vector<custom_class>,我想加入逗号分隔的字符串。

我找到了代码:

std::stringstream s;
std::string delimeter = ",";
copy(v.begin(), v.end(), std::ostream_iterator<int>(s, delimeter.c_str()));

非常适合加入单一类型的向量,例如int。但是,我想加入custom_class的某个属性。

我可以使用copy仅复制和加入custom_class的某个属性吗?

例如,我的vector<custom_class>看起来像是:

v[0].A = 1
v[0].B = 2
v[0].C = 3

v[1].A = 1
v[1].B = 2
v[1].C = 3

v[2].A = 1
v[2].B = 2
v[2].C = 3

v[3].A = 1
v[3].B = 2
v[3].C = 3

我想使用std::copy仅加入属性B的值(作为示例)来返回值:

2,2,2,2

如果没有循环v表达,这样的事情是否可能?

2 个答案:

答案 0 :(得分:3)

您可以使用标准算法std::transform代替算法std::copy

例如

std::transform( v.begin(), v.end(), std::ostream_iterator<int>( s, "," ),
                []( const custom_class &c ) { return c.B; } );

另一种方法是使用标题std::accumulate中声明的算法<numeric>和函数std::to_string

例如

std::string s = std::accumulate( v.begin(), v.end(), std::string(),
                                 []( std::string &s, const custom_class &c ) 
                                 {
                                     return ( s += std::to_string( c.B ) + ',' ); 
                                 } );

答案 1 :(得分:1)

加入一个字符串有点奇怪,因为你需要专门处理空容器。因此,推广自己的算法可能最简单。这是一个采用提取器谓词参数的方法:

#include <iterator>
#include <sstream>
#include <string>
#include <utility>

template <typename C, typename E>
std::string join(char const * delim, C const & c, E && e)
{
  using std::begin;
  using std::end;

  auto it = begin(c), eit = end(c);

  if (it == eit) { return {}; }

  std::ostringstream os;

  os << e(*it);

  while (++it != eit) { os << delim << e(*it); }

  return os.str();
}

用法示例:

#include <functional>
#include <iostream>
#include <vector>


int main()
{
  std::vector<std::pair<int, int>> v { { 1, 4 }, { 2, 8 }, { 3, 19 }};
  std::cout << join(" | ", v, std::mem_fn(&std::pair<int, int>::second)) << "\n";
}

如果您只想在不应用提取器的情况下打印元素本身,则可以传递某种“身份”提取器,例如std::forward的合适实例。事实上,我们可以将其作为默认参数烘焙:

template <typename C,
          typename E = typename C::value_type const &(&)(typename C::value_type const &)>
std::string join(char const * delim,
                 C const & c,
                 E && e = static_cast<typename C::value_type const &(&)(typename C::value_type const &)>(std::forward))

现在我们可以说例如:

std::vector<int> w { 1, 4, 2, 8, 3, 19 };
std::cout << join(", ", w) << "\n";