2016-02-12 139 views
1

我正在編寫一個練習編譯器,並且lookup_helper(key,current)返回指向某個符號的指針,如果它在當前範圍中找到的話。 for()循環遍歷所有範圍並搜索某個符號,直到它找到並返回它。否則返回nullptr。如果函數值爲空則返回

Symbol * lookup() 
    { 

    //.... 
    //.... 

    //search all scopes 
    for (int i = Scopes.size(); i > 0; i--) 
      { 
       Scope current = Scopes[i - 1]; 

       if (lookup_helper(key, current)) //not good design 
        return lookup_helper(key, current); //calling second time 

      } 
     return nullptr; //not found 
    } 

這段代碼不是調用lookup_helper()兩次嗎?一次在if()和一次在返回?我有這個問題的解決方案,但我正在尋找一個更優雅的解決方案,只調用lookup_helper一次(也不想創建一些變量來存儲返回值)。也許我所問的是不可能的,因爲我必須跳到代碼的執行過程中來確定lookup_helper是否返回nullptr。

我會想象優雅:(不喜歡這個工作)

for (int i = Scopes.size(); i > 0; i--) 
     { 
      Scope current = Scopes[i]; 

      return (ifnotnull) lookup_helper(key, current); 

     } 
+4

爲什麼不使用局部變量? – Jarod42

+0

在OP中,我說這不是我想要做的事情。我正在尋找一種語言功能(類似lambda或其他東西),只允許它調用一次功能 – user3465668

+0

最後一個例子是優雅的嗎?仍然調用'lookup_helper'兩次,再加上檢查(試圖)兩次? – LogicStuff

回答

1

在最內側範圍局部變量之前完成,你可以做

for (int i = Scopes.size(); i > 0; i--) { 
    if (auto ret = lookup_helper(key, Scopes[i])) { 
     return ret; 
    } 
} 

或更傳統的

for (int i = Scopes.size(); i > 0; i--) { 
    auto ret = lookup_helper(key, Scopes[i]); 
    if (ret) { 
     return ret; 
    } 
} 
+0

if()語句返回什麼?如果ret不爲null,則返回true?我喜歡 – user3465668

+0

@ user3465668'lookup_helper'函數返回一個指針,所以'auto ret'是一個指針類型。 'operator ='返回對被修改對象的引用(即一個指針)。最後,'T * ptr = nullptr;如果(ptr){...}'說明爲什麼上面的if(auto ret = lookup_helper(...))'工作。 –

2

是的,你的代碼調用lookup_helper兩次。如果某些編譯器知道該函數是「純」的(使用GCC術語),則可以消除第二個調用。但是,在C++中,這些「優化」之一是更好地手動和明確地完成的。

至於如何避免第二個電話,它通常是由存儲在一箇中間變量的結果,試圖分析其

... 
Symbol *symbol = lookup_helper(key, current); 
if (symbol != nullptr) 
    return symbol; 
.... 
0

是你的代碼將調用lookup_helper兩次。一個簡單的解決方案是將結果存儲到局部變量中:

... 
for(auto & scope : Scopes) { 
    auto ret = lookup_helper(key, scope); 
    if(ret) return ret; 
} 
... 
相關問題