我正在开发一个函数,它目前按原样运行。
void ceasarShift( CeasarText& text, int amount ) {
// Bound amount to the number of characters in the alphabet
amount %= 26;
for ( std::size_t i = 0; i < text._originalText.length(); i++ ) {
char c = text._originalText[i] + amount;
text._shiftedText += c;
}
}
此函数所使用的类是一个具有2个std :: string成员变量的简单类。当这个类通过引用传递给这个类的友元函数时,它接受已设置的original
字符串并使用它来填充shifted
字符串,该字符串在此函数看到它之前为空。完成for循环后,函数完成,类对象通过引用以新更新的shifted
字符串返回,原始文件未经修改。
我在考虑使用std::transform
和lambda
来执行相同的任务。这就是我的尝试。
void ceasarShift( CeasarText& text, int amount ) {
// Bound amount to the number of characters in the alphabet
amount %= 26;
/*for ( std::size_t i = 0; i < text._originalText.length(); i++ ) {
char c = text._originalText[i] + amount;
text._shiftedText += c;
}*/
std::transform( text._originalText.begin(), text._originalText.end(),
text._shiftedText.begin(),
[amount]( unsigned char c ) -> unsigned char { return c + amount; }
);
}
我最终得到一个Debug Assertion失败!窗口消息Expression: cannot seek string iterator past end
我想知道我的lambda
是否错误,或者我是否需要使用std::transform
以外的其他内容。
修改
我也试过这个,这就像第一个循环一样:
{
amount %= 26;
for ( auto& c : text._originalText )
text._shiftedText += (c + amount);
}
我似乎无法让lambda作为std::transform
的谓词正常工作。
答案 0 :(得分:3)
根据this link,std::transform
的行为相当于:
template <class InputIterator, class OutputIterator, class UnaryOperator>
OutputIterator transform (InputIterator first1, InputIterator last1,
OutputIterator result, UnaryOperator op)
{
while (first1 != last1) {
*result = op(*first1); // or: *result=binary_op(*first1,*first2++);
++result; ++first1;
}
return result;
}
这意味着OutputIterator
的容器应该保留足够的空间,否则,当++result
答案 1 :(得分:3)
问题不在于你的lambda。两个片段之间的区别在于,for循环使用operator+=
将元素附加到字符串,但您的变换假定元素已经存在。如果要使用transform追加到字符串,则需要使用插入迭代器。特别是后插入迭代器。因此,不要传递text._shiftedText.begin()
,而是传递std::back_inserter(text._shiftedText)
。
std::transform( text._originalText.begin(), text._originalText.end(),
std::back_inserter(text._shiftedText),
[amount]( unsigned char c ) -> unsigned char { return c + amount; }
);