在 C++ 中连接类方法提供的字符串

Concatenate strings provided by a class method in C++

本文关键字:字符串 类方法 C++ 连接      更新时间:2023-10-16

我的问题很简单:我有一个动态的对象数组,它们有一个返回字符串的方法。我想将所有这些字符串连接在一起。

如果我有一个字符串数组而不是带有返回的方法的对象字符串,这将是一个微不足道的任务:

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

但就我而言,它看起来像这样:

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") };

我想使用标准库算法,因为我确信这些算法是高效且我不必调试的东西,但这太难阅读了并理解:

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());

未来的维护者可能会(并且理所当然地)追捕我来打面对我不必要地使一项简单的任务复杂化,那本可以完成:

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

这里有没有我看不到的更容易的东西,或者情况确实如此应该让标准库休息的地方,并使用 for 循环(这是无论如何,积累归结为什么)?

如果你坚持使用 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();});

编辑:也许更易于复制的声明

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

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

std::string & operator +=( std::string &s, const Foo &f )
{
   return ( s += f.name() );
}

我不明白 std::for_each、std::accumulate 会如何给你带来性能上的胜利(你的向量是否足够大以至于这很重要?)。如果对您很重要,您可能需要进行时间分析。

当复杂性不是性能关键时,我会选择可读性和可维护性,而不是使用复杂性。