2014-01-22 174 views
0

我有一個基本函數來檢查這個單詞是否是一個鍵。問題是我的try catch塊總是捕獲一個out_of_range異常,即使密鑰存在。這個問題只發生在我的isExclusion函數中。如果我使用靜態字符串檢查isExclusion函數的外部,那麼at不會拋出異常。std :: map函數總是拋出異常

此外,有沒有更好或更有效的方法來檢查密鑰是否存在?我寧願不必遍歷鍵列表。

#ifndef TITLES_H_ 
    #define TITLES_H_ 

    #include <algorithm> 
    #include <string> 
    #include <vector> 
    #include <map> 

    static std::map<std::string, int> exclusions; 
    static std::vector<std::string> titles; 

    bool isExclusion(std::string word); 

#endif 

#include "titles.h" 
#include <iostream> 

bool isExclusion(std::string word) 
{ 
    try 
    { 
     exclusions.at(word);  
    } 
    catch (std::out_of_range e) 
    { 
     return false; 
    } 

    return true; 
} 

#include <iostream> 
#include "titles.h" 

int main() 
{ 
    exclusions["is"] = 1; 
    exclusions["the"] = 1; 
    exclusions["of"] = 1; 
    exclusions["and"] = 1; 
    exclusions["a"] = 1; 
    exclusions["but"] = 1; 
    exclusions["as"] = 1; 

    titles.push_back("Descent of Man"); 
    titles.push_back("The Ascent of Man"); 
    titles.push_back("The Old Man and The Sea"); 
    titles.push_back("A Portrait of the Artist As a Young Man"); 
    titles.push_back("A Man is a Man but Bubblesort IS A DOG"); 
    std::sort(titles.begin(), titles.end()); 

    try 
    { 
     exclusions.at("the"); 
    } 
    catch(std::out_of_range e) 
    { 
     std::cout << "Not found\n"; 
    } 
    std::cout << "Exclusion?: " << isExclusion("hello") << std::endl; 
    std::cout << "Exclusion?: " << isExclusion("the") << std::endl; 

    for(auto i = titles.begin(); i != titles.end(); i++) 
    { 
     std::cout << *i << "\n"; 
    } 

    return 0; 
} 
+0

我忘了補充我有標誌-lm -lcrypt -02 -std = C++ 11 -pipe -DONLINE_JUDGE – Taztingo

+0

是在最後兩個街區的一部分同一個文件? – Nabla

+0

不,他們在單獨的文件。 – Taztingo

回答

2
static std::map<std::string, int> exclusions; 

exclusions定義static。全局變量的範圍僅限於其各自的編譯單元。這樣可以在多個編譯單元中重用名稱。

您可以在兩個編譯單元中按#include "titles.h"包含此行。因此,您實際上創建了兩個具有相同名稱的地圖,每個地圖僅限於其編譯單元。

main

exclusions["is"] = 1; 
exclusions["the"] = 1; 
exclusions["of"] = 1; 
exclusions["and"] = 1; 
exclusions["a"] = 1; 
exclusions["but"] = 1; 
exclusions["as"] = 1; 

這些線因此不同的地圖上操作比函數

bool isExclusion(std::string word) 
{ 
    try 
    { 
     exclusions.at(word);  
    } 
    catch (std::out_of_range e) 
    { 
     return false; 
    } 

    return true; 
} 
在其他單元

。第二單元中的exclusions實際上總是空的。

您需要刪除關鍵字static並將定義移至其中一個單元(最好爲main)。要還使用變量中的其他單元,你必須有聲明爲extern

extern std::map<std::string, int> exclusions; 

但是它會好得多在所有不使用全局變量,並通過地圖和文字載體的引用功能代替。當你在它的時候也使它們成爲const引用。 (該功能不會對其進行修改。)

bool isExclusion(const std::map<std::string, int>& exclusions, const std::string& word) 
+1

當你處理它時,你最好通過'const'參考來傳遞'exclusions'和'word'。 –

+1

喜歡這個答案,謝謝。幫了很多。 – Taztingo

2

你的問題是這一行:

static std::map<std::string, int> exclusions; 

通過定義該變量爲static,你在兩個創建兩個單獨的map小號單獨的翻譯單位。 main()正在使用一個maptitles.cpp正在使用其他。相反,像這樣聲明變量:

extern std::map<std::string, int> exclusions; 

。 。 。然後加入這一行到您的titles.cpp文件:

std::map<std::string, int> exclusions; 

這將導致全局變量是所有翻譯單元可見的,並且只會有一個實際的地圖。

一般來說是一個壞主意,用在頭文件中的關鍵字static(除了structclass內聲明類變量)。有一些例外,但它們是圖書館作者通常擔心的深奧情景。