将 for 循环转换为使用 std::transform
Converting a for loop to use std::transform instead
我正在开发一个功能,它目前可以正常工作。
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;
}
}
这个函数采用的class是一个简单的class,有2个std::string成员变量。当此 class 通过引用传递给 class 时,它采用已设置的 original
字符串并使用它来填充 shifted
字符串在这个函数看到它之前它是空的。当 for 循环完成时,函数结束,class 对象通过引用返回,并带有新更新的 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; }
);
}
最后我得到了调试断言失败! Window 留言 Expression: cannot seek string iterator past end
我想知道我的 lambda
是否有误,或者我是否需要使用 std::transform
以外的其他东西。
编辑
我也试过这个,它像第一个循环一样工作:
{
amount %= 26;
for ( auto& c : text._originalText )
text._shiftedText += (c + amount);
}
我似乎无法让 lambda 作为 std::transform
的谓词正常工作。
根据 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
的容器要预留足够的space,否则在++result
时会超出范围
问题不在于您的 lambda。您的两个代码段之间的区别在于,您的 for 循环使用 operator+=
将元素附加到您的字符串,但您的转换假定元素已经存在。如果要使用转换附加到字符串,则需要使用插入迭代器。特别是一个后插入迭代器。所以不是传递 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; }
);
我正在开发一个功能,它目前可以正常工作。
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;
}
}
这个函数采用的class是一个简单的class,有2个std::string成员变量。当此 class 通过引用传递给 class 时,它采用已设置的 original
字符串并使用它来填充 shifted
字符串在这个函数看到它之前它是空的。当 for 循环完成时,函数结束,class 对象通过引用返回,并带有新更新的 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; }
);
}
最后我得到了调试断言失败! Window 留言 Expression: cannot seek string iterator past end
我想知道我的 lambda
是否有误,或者我是否需要使用 std::transform
以外的其他东西。
编辑
我也试过这个,它像第一个循环一样工作:
{
amount %= 26;
for ( auto& c : text._originalText )
text._shiftedText += (c + amount);
}
我似乎无法让 lambda 作为 std::transform
的谓词正常工作。
根据 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
的容器要预留足够的space,否则在++result
问题不在于您的 lambda。您的两个代码段之间的区别在于,您的 for 循环使用 operator+=
将元素附加到您的字符串,但您的转换假定元素已经存在。如果要使用转换附加到字符串,则需要使用插入迭代器。特别是一个后插入迭代器。所以不是传递 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; }
);