[英]Operator precedence and order of evaluation in the implementation of std::transform
概括
我偶然發現了std::transform
的實現,但我無法弄清楚為什么它在我們就地轉換容器的情況下有效。 特別是,我發現這個表達式令人困惑*d_first++ = unary_op(*first1++);
.
代碼
使用此處找到的第一個std::transform
實現https://en.cppreference.com/w/cpp/algorithm/transform ,我編寫了以下示例代碼:
#include <iostream>
template< class InputIt,
class OutputIt,
class UnaryOperation >
OutputIt transform( InputIt first1,
InputIt last1,
OutputIt d_first,
UnaryOperation unary_op )
{
while (first1 != last1) {
*d_first++ = unary_op(*first1++);
}
return d_first;
}
int main() {
int arr[5] {1,2,3,4,5};
transform(std::begin(arr),std::end(arr),
std::begin(arr),
[](auto i){return i*i;});
for (auto& elem : arr) std::cout << elem << std::endl;
return 0;
}
試圖解釋
在閱讀了 C++ 標准、Cpp 參考等之后,我想我可能能夠解釋在那個令人困惑的(對我而言)聲明中發生了什么。 讓我們分解這個表達式:
*d_first++ = unary_op(*first1++); // same as A = B;
B
上發生的情況,即unary_op(*first1++)
*first1++
表示*(first1++)
表示 a) 復制取消引用的first1
並 b) 將其傳遞給 function,然后 c) 遞增迭代器。first1
內乘以unary_op
。B
被評估,是時候處理分配了。B
分配給d_first
的取消引用值。d_first
迭代器。這樣,兩個迭代器“在同一頁上”,這意味着它們迭代的 arrays 的 position 相同。
問題
我的問題是:
A) 上述解釋正確嗎?
B)該表達式中的哪些操作是評估和哪些計算?
C) 由於*first1++
轉換為*(first1++)
但取消引用發生在遞增之前,記住這不是令人困惑嗎? 但是, (*first1)++
意味着完全不同的東西,即取消引用first1
並將其傳遞給 function 然后將該值加一; 不是迭代器? 有什么提示可以記住如何在這種表達方式中解開自己的糾結嗎?
只回答 C)。
有什么提示可以記住如何在這種表達方式中解開自己的糾結嗎?
*i++
, *dst++ = do_something_with(*src++);
等,是 C++ 和 C 中成熟的模式。 因此,建議是:
如果您的意思是*(first++)
,請將其寫為*first++
,因為它最不令人驚訝。 (並習慣以正確的方式閱讀這個表達。)
如果您的意思是(*first)++
,那么就這樣寫。 (無論如何,您別無選擇。)括號的存在立即表明,其意圖與*first++
不同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.