簡體   English   中英

std::transform 實現中的運算符優先級和求值順序

[英]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; 
  1. 首先解決B上發生的情況,即unary_op(*first1++)
  2. 現在解析括號*first1++表示*(first1++)表示 a) 復制取消引用的first1並 b) 將其傳遞給 function,然后 c) 遞增迭代器。
  3. 復制的取消引用 first1 在first1內乘以unary_op
  4. 現在B被評估,是時候處理分配了。
  5. B分配給d_first的取消引用值。
  6. 當這個賦值完成時,在我們 go 到下一條語句(無論可能是什么)之前遞增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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM