3

My problem is rather simple: I have a dynamic array of objects that have a method returning a string. I want to concatenate all these strings together.

If I had an array of strings instead of objects with a method returning a string, this would be a trivial task:

std::vector<std::string> v{ "f", "o", "o" };
std::string const x = std::accumulate(v.begin(), v.end(), std::string());

But in my case it rather looks like this:

struct foo
{
    foo(std::string const & name) : name_(name) {}
    std::string const & name() const { return name_; }

    private:
        std::string const name_;
};

std::vector<foo> v{ foo("f"), foo("o"), foo("o") };

I would like to use the standard library algorithms as I am sure that those are efficient and something that I don't have to debug, but this is too hard to read and understand:

std::vector<std::string> transformed(v.size());
std::transform(v.begin(), v.end(), transformed.begin(),
    [](foo const & f) { return f.name(); });
std::string const x = std::accumulate(transformed.begin(), transformed.end(),
    std::string());

The future maintainers would probably (and rightfully so) hunt me down to punch me in the face for needlessly complicating an easy task, that could have been done with:

std::string x;
for(auto const & f : v)
    x += f.name();

Is there something easier here that I am not seeing, or is this indeed the case where one should let the standard libraries rest, and use the for loop (which is what accumulate boils down to anyway)?

4

4 回答 4

6

如果您坚持使用 STL,还有另一个版本std::accumulate

template< class InputIt, class T, class BinaryOperation >
T accumulate( InputIt first, InputIt last, T init, BinaryOperation op );

然后你的代码可以变成

std::string const x = std::accumulate(v.begin(), v.end(), std::string(),
                         [](std::string a, foo const& b){return a += b.name();});

编辑:也许对复制省略更友好的声明

于 2013-10-14T16:53:18.127 回答
2

我只会使用 for 循环方法。它更易于阅读,并且您不需要调试或测试(至少与您编写自己的某种算法的级别不同)。仅仅因为它不是利用 std 库的解决方案并不意味着它是易于维护的明智解决方案。

于 2013-10-14T16:47:52.850 回答
0

我看不到 std::for_each, std::accumulate 将如何为您带来性能上的胜利(您的向量是否足够大以至于这很重要?)。如果对您很重要,您可能想要进行时序分析。

当复杂性不是性能关键时,我会追求可读性和可维护性。

于 2013-10-14T17:01:41.537 回答
0

你可以写运算符 +=。某事作为

std::string & operator +=( std::string &s, const Foo &f )
{
   return ( s += f.name() );
}
于 2013-10-14T16:54:06.020 回答