2013-07-12 20 views
1

我想在條件表達式中定義變量,以便變量範圍在if子句內。這工作得很好,如何檢查密鑰是否存在於std :: map中,並在if條件中獲取map :: iterator?

if (int* x = new int(123)) { }

當我試圖做地圖:迭代類似的事情,

if ((map<string, Property>::iterator it = props.find(PROP_NAME)) != props.end()) { it->do_something(); }

error: expected primary-expression before ‘it’

做什麼int*之間的區別和map::iterator

+0

請不要像這樣分配動態內存。如果發生異常,您可能會發現內存泄漏。要麼使用智能指針,要麼首先考慮一個簡單的'int'是否需要處於動態內存中。 –

+1

呃...只是不。 –

回答

5

在這方面int *map::iterator之間沒有區別。您正在使用的周圍語義結構與int *map::iterator有所不同,這就是爲什麼一個編譯和其他編譯沒有。

隨着if你有一個選擇,要麼

if (declaration) 

if (expression) 

宣言不表達。您不能在更大的表達式中使用聲明作爲子表達式。您不能將聲明用作明確比較的一部分,這正是您嘗試執行的操作。

例如,如果你試圖做同樣的事情與int *,這樣

if ((int* x = new int(123)) != NULL) 

的代碼將無法編譯不能通過完全一樣的原因,你的map::iterator代碼不編譯。

你必須使用

if (int* x = new int(123)) 

int* x = new int(123); 
if (x != NULL) 

int* x; 
if ((x = new int(123)) != NULL) 

正如你可以在上面看到,int *展品完全相同的行爲map::iterator

在您的示例中,不可能聲明it並在if的條件下執行與props.end()的比較。你將不得不使用上述一個變型相反,即要麼

map<string, Property>::iterator it = props.find(PROP_NAME); 
if (it != props.end()) 

map<string, Property>::iterator it; 
if ((it = props.find(PROP_NAME)) != props.end()) 

您可以選擇自己喜歡的更多。

P.S.當然,正式,你也可以寫

if (map<string, Property>::iterator it = props.find(PROP_NAME)) 

但它不會做你想要它做的事情(不比較迭代器價值props.end()),並且可能不能編譯,因爲迭代器類型可能是不可兌換爲bool

+0

關於'聲明不是表達式',(int * x = new int(123))的值是什麼?這可以放在if() – woodings

+1

@woodings:正如我上面所說,這種形式是由一個單獨的,專門的C++語言語義分支來處理的。它不是「if(表達式)」分支,而是「if(聲明)分支」。該語言單獨定義它。它基本上說,聲明的變量被隱式轉換爲'bool',並且該值用於做出分支決策。這不會將聲明轉換爲表達式,也不允許您在其他更大的表達式中使用聲明。 – AnT

0

映射迭代器包含firstsecond,它們分別指向鍵和值。 要訪問值的成員,使用it->second.do_Something()

1

這裏有一種方法將其限制在一個範圍:

{ 
    auto it = props.find(PROP_NAME); 
    if (it != props.end()) { 
     it->do_something(); 
    } 
} 

當然,這範圍是不是技術上的,「如果範圍」,但應該只是服務以及所有實際意圖和目的。

由於AndreyT already explained(+1),聲明不能超越(),你沒有爲int使用,但你做的迭代器。