4

我正在练习 C++,所以这不是将要投入生产的代码,但我很想知道:

我有一个指向类型对象的指针向量Player

std::vector<Player*> _players;

std::string当我调用它的方法时,每个玩家都会返回他的名字get_name(),例如:

std::string player0_name = _players[0]->get_name();

我想将所有玩家名称传递给一个函数,该函数期望它们作为对字符串向量的引用:

void all_player_names( std::vector< std::string >& );

现在我知道通过一些临时变量很容易做到这一点。我可以首先创建一个字符串向量,将所有玩家名称存储在那里,然后将其all_player_names作为参考传递给函数。

但我正在寻找一种无需创建临时变量的方法。它应该类似于 Python 中的列表推导。它必须遍历指针数组,在每个Player指针上调用get_name()函数,从返回的字符串中构建一个向量并将其直接传递给函数all_player_names。我假设它应该可以使用 lambda 函数和 STL 中的一些算法,但我不知道是哪一个。

所以它看起来或多或少应该是这样的:

all_player_names(<function that i'm looking for>(
    _players, [](Player* p) { return p->get_name();}
);

STL中有这样的算法吗?

4

4 回答 4

5

最简单的方法是使用累积并使用将通过二进制操作传递并返回的临时变量:

std::accumulate(_players.begin(), _players.end(), 
 std::vector<std::string>(),
 [](std::vector<std::string>& vector, const Player* elem) 
   {
    vector.push_back(elem->get_name());
    return vector;
   });

由于移动语义,它在 C++11 中应该几乎没有性能开销。

于 2013-11-14T08:56:39.770 回答
4

在我看来,最好使用标准算法 std::transform 而不是 std::accumulate。在这种情况下,std::transform 的语义比 std::accumulate 的语义更清晰。例如

    struct Player
    {
    public:
        Player( const std::string &s ) : s( s ) {}
        const std::string & get_name() const
        {
            return s;
        }
    private:
        std::string s;
    };

    std::vector<Player *> v1;

    v1.push_back( new Player( "Hello" ) );
    v1.push_back( new Player( "Player" ) );

    std::vector<std::string> v2;
    v2.reserve( v1.size() );


    std::transform( v1.begin(), v1.end(), std::back_inserter( v2 ), 
                    std::mem_fun( &Player::get_name ) );

    for ( const std::string &s : v2 ) std::cout << s << ' ';
    std::cout << std::endl;
于 2013-11-14T09:18:45.880 回答
0

您想要的是使用 lambda 表达式(或匿名函数)。

现在可以使用 C++11,但不能使用以前的版本。问题也在这里处理。

在你的情况下,我会在新的 Players 类中使用一个方法:

class Players {
public:
    void addPlayer(Player*);
    void removePlayer(Player*);
    vector<string> getNames() {
      std::vector<string> names;
      for(unsigned int i = 0; i != players_.size(); ++i) {
        names.push_back(players_[i]->getName());
      }
    return names;
    }
private:
vector<Player*> players_;

};

于 2013-11-14T09:02:50.427 回答
0

如果你有一个参数是 const ref 你别无选择,只能构造一个变量。你的 const ref 应该指向一些现有的对象。您可以更改函数以获取指向 function 的指针和指向 的 const ref std::vector<Player*>。使函数接受一个指向Player并返回他的名字的指针。

于 2013-11-14T08:54:04.593 回答