lambda采取`char`参数

时间:2016-04-20 08:10:04

标签: c++ string c++11 lambda

如何定义lambda以从char获取string iterator?在下面的代码中,lambda detect_bracket对输入参数x有疑问。

我不想从字符串中删除所有括号,只是在开头和结尾。

auto detect_bracket = [](char* x){ return(')' == x || '(' == x);};

this->str.erase(std::remove_if(str.begin(), str.begin(),
            detect_bracket)
);
this->str.erase(std::remove_if(str.back(), str.back(),
            detect_bracket)
);

3 个答案:

答案 0 :(得分:4)

您应该将char作为lambda的参数类型std::remove_if,因为谓词函数的签名应该直接检查元素。

auto detect_bracket = [](char x){ return(')' == x || '(' == x);};
this->str.erase(std::remove_if(str.begin(), str.end(),
        detect_bracket)
);

注意std::string::back()不适用于std::remove_if。它将返回char并且std::remove_if期望迭代器表示的范围。

而且str.begin(), str.begin()只是一个空范围,如果你只是想在开头和结尾删除元素,你可以

auto detect_bracket = [](char x){ return(')' == x || '(' == x);};
if (!this->str.empty()) {
    this->str.erase(std::remove_if(str.begin(), str.begin() + 1, detect_bracket), str.begin() + 1);
}
if (!this->str.empty()) {
    this->str.erase(std::remove_if(str.end() - 1, str.end(), detect_bracket), str.end());
}

注意我们需要为std::string::erase指定正确的结束迭代器,因为std::remove_if将返回一个迭代器,即使它什么也没找到,然后char将被错误地删除。

LIVE

答案 1 :(得分:2)

std::remove_if是具有以下签名的函数:

template< class ForwardIt, class UnaryPredicate >
ForwardIt remove_if( ForwardIt first, ForwardIt last, UnaryPredicate p ); 
           

p - 如果要删除元素,则返回true的一元谓词。   谓词函数的签名应等同于以下内容:

bool pred(const Type &a);
     

类型Type必须是ForwardIt类型的对象   取消引用然后隐式转换为Type。

您只需将功能参数从char*更改为char

答案 2 :(得分:0)

多个remove_iferase调用无论如何都会修改/使string无效。为什么不简单地创建一个新的string,并有条件地从第0个位置或第1个位置分配源字符串?然后assign直到最后一个或倒数第二个字符,有条件地

string target;
target.assign(source.begin() + skip_if_bracket_at_begin, 
    source.end() - skip_if_bracket_at_end);