-1

在尝试从向量中删除字符串时,我看到了一些严重的错误消息。我正在尝试使用擦除删除成语,但它不起作用。这里有一些片段来说明我的困境。

team.players.erase( remove(team.players.begin(), team.players.end(),
                            player_name), team.players.end());

team.players 在这个结构中声明:

struct team 
{
    string name;
    player captain;
    vector<player> players;

};

向量 team.players 在程序运行时动态填充,并且在某些时候,用户可以选择通过菜单删除玩家。

if (select_option == PRINT_TEAM) print_team(team);
    if (select_option == CHANGE_TEAM_NAME) change_team_name(team);
    if (select_option == CHANGE_CAPTAIN) change_captain(team);
    if (select_option == ADD_PLAYER) add_player(team);
    if (select_option == REMOVE_PLAYER) remove_player(team);
    if (select_option == QUIT) exit(0);

但是,当我试图编译我的程序(clang++)时,我得到了这些错误,早在调用函数之前。以下是错误:

/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/algorithm:865:22: error:      invalid operands to binary expression ('player' and 'const      std::__1::basic_string<char>')
        if (*__first == __value_)
            ~~~~~~~~ ^  ~~~~~~~~
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/algorithm:2125:22: note:
      in instantiation of function template specialization
      'std::__1::find<std::__1::__wrap_iter<player *>, std::__1::basic_string<char> >'
      requested here
    __first = _VSTD::find(__first, __last, __value_);
                     ^
program2.cpp:172:25: note: in instantiation of function template specialization
      'std::__1::remove<std::__1::__wrap_iter<player *>, std::__1::basic_string<char>
      >' requested here
    team.players.erase( remove(team.players.begin(), team.players.end(),
                        ^
2 errors generated.

知道如何解决这个问题吗?

4

3 回答 3

3

该错误消息非常神秘,尤其是对于初学者而言,但似乎编译器无法找到operator==将类的实例playerstd::string对象进行比较的实现。

也许您真正想要的是 using std::remove_if,指定一个自定义条件,在该条件下您将播放器的名称与std::string要删除的存储名称进行比较。

您可以使用 lambda 表达此自定义条件,例如:

team.players.erase( 
    std::remove_if(
        team.players.begin(), 
        team.players.end(),

        [&player_name](const player& p) {
            return p.name == player_name;
        }),
    team.players.end()
);
于 2017-09-08T10:16:29.050 回答
0

你想要std::remove_if,没有std::remove。您必须提供一个函数,该函数接受一个播放器(用于避免复制的 const 引用)并返回 bool。

例如(假设player有一个字符串成员name

team.players.erase( 
    remove_if(
        team.players.begin(), 
        team.players.end(), 
        [&player_name](const player & p) { return p.name == player_name }), 
    team.players.end());
于 2017-09-08T10:17:16.553 回答
0

问题在于该std::remove()函数用于bool operator==()将 的元素std::vector<player>player_name类型为 的变量进行比较std::string

这就是如何std::remove()识别它应该删除向量的哪些元素(或者,更好的是,在容器的末尾移动)的方式。

但是,没有bool operator==(const player& p, const std::string& name)定义,这并不奇怪,因为您必须自己做。更好的方法,在这种情况下,恕我直言,是使用std::remove_if()而不是std::remove(),因为std::remove_if()它需要一个一元函数(一个带有一个参数并返回布尔值的函数),它调用它是为了确定它是否应该删除元素。

team.players.erase(remove_if(team.players.begin(), team.players.end(),
    [&player_name](const auto& player) { return player.name == player_name; });

(注意:我假设playerclass/struct 有nametype的成员std::string)。

如果您想尝试这种operator==()方法,则必须定义如下内容:

bool operator==(const player& p, const std::string& name) {
    return p.name == name;
}

bool operator==(const std::string& name, const player& p) {
    return p.name == name;
    // Or, to be more general, you could use
    // return operator==(p, name);
    // here (to call the operator==() version with switched arguments)
}

(是的,您应该返回两个版本,因为 - 通常 - 比较使用==应该是对称的)。

于 2017-09-08T10:24:57.997 回答