2011-11-24 124 views
3

我曾經有一個正常的成員變量,將其在構造器來初始化如下:平移正常成員變量靜態成員變量導致問題

ResourceSaveFunctions[OBJECTS_IDENT] = NULL; 
ResourceSaveFunctions[SPRITES_IDENT] = &GMProject::SaveSprite; 
ResourceSaveFunctions[SOUNDS_IDENT] = &GMProject::SaveSound; 
ResourceSaveFunctions[BACKGROUNDS_IDENT] = &GMProject::SaveBackground; 
ResourceSaveFunctions[PATHS_IDENT] = NULL; 
ResourceSaveFunctions[SCRIPTS_IDENT] = NULL; 
ResourceSaveFunctions[FONTS_IDENT] = NULL; 
ResourceSaveFunctions[TIMELINES_IDENT] = NULL; 
ResourceSaveFunctions[ROOMS_IDENT] = NULL; 
ResourceSaveFunctions["extension"] = &GMProject::SaveExtension; 
ResourceSaveFunctions[INCLUDES_IDENT] = NULL; 
ResourceSaveFunctions[TRIGGERS_IDENT] = NULL; 

變量是與作爲密鑰串的圖,並且作爲數據成員函數指針。這工作得很好。然而,正如我所說,我相信這張地圖應該是靜態的(?) - 地圖的原因只是爲了確定程序在閱讀文件時應該做些什麼。 - NULL意思是「不做任何特別的事情」。

所以我把它改成如下:

std::map<std::string, GMProject::GMProjectMemFn> GMProject::ResourceSaveFunctions_INIT() { 
    std::map<std::string, GMProjectMemFn> tmp; 
    tmp.insert(std::make_pair(OBJECTS_IDENT,NULL)); 
    tmp.insert(std::make_pair(SPRITES_IDENT, &GMProject::SaveSprite)); 
    tmp.insert(std::make_pair(SOUNDS_IDENT, &GMProject::SaveSound)); 
    tmp.insert(std::make_pair(BACKGROUNDS_IDENT, &GMProject::SaveBackground)); 
    tmp.insert(std::make_pair(PATHS_IDENT, NULL)); 
    tmp.insert(std::make_pair(SCRIPTS_IDENT, NULL)); 
    tmp.insert(std::make_pair(FONTS_IDENT, NULL)); 
    tmp.insert(std::make_pair(TIMELINES_IDENT, NULL)); 
    tmp.insert(std::make_pair(ROOMS_IDENT, NULL)); 
    tmp.insert(std::make_pair("extension", &GMProject::SaveExtension)); 
    tmp.insert(std::make_pair(INCLUDES_IDENT, NULL)); 
    tmp.insert(std::make_pair(TRIGGERS_IDENT, NULL)); 
    return tmp; 
} 
const std::map<std::string, GMProject::GMProjectMemFn> GMProject::ResourceSaveFunctions(GMProject::ResourceSaveFunctions_INIT()); 

如果這些東西都在頭部聲明:

static const std::map<std::string, GMProjectMemFn> ResourceSaveFunctions; 
static std::map<std::string, GMProjectMemFn> ResourceSaveFunctions_INIT(); 

現在編譯突然帶來了很多的錯誤。

1> C:\程序Files \ Microsoft的Visual Studio 10.0 \ VC \包括\實用程序(163):錯誤C2440:初始化:不能從 'INT' 轉換爲 'GMProject :: GMProjectMemFn'

這是關於NULL的轉換。但是,這不僅僅是可能嗎?爲什麼這是不可能的(但在以前的方法中)? 我應該在這裏使用明確的演員嗎?

編輯:定義如下 GMProjectMemFn:

typedef void (GMProject::*GMProjectMemFn)(const pTree&) const; 

ptree中是一個容器。

+0

'GMProjectMemFn'的定義是什麼? – Constantinius

+0

你有C++ 11嗎? –

+0

你自己在實現虛擬表嗎?我不清楚你的大地圖o'成員函數指針是否需要......它看起來像是來自C程序的東西。 –

回答

1

std::make_pair創建pair<T1, T2>在類型T1T2被隱式地從類型的參數中推演出來。 NULL擴展爲0(或0L),因此在您的情況下,make_pair返回pair<string, int>(或pair<string, long>)。

然後您嘗試將pair<string, int>傳遞給map<string, GMProject::GMProjectMemFn>::insert(),但這需要pair<string, GMProjectMemFn>

std::pair具有一般的拷貝構造,這將嘗試對每個成員的隱式轉換:

template <class U, class V> 
    pair (const pair<U,V> &p) : first(p.first), second(p.second) { } 

但在你的情況下,這需要轉換const int&的指針,這是不允許的。

在您的原始案例中,您直接將NULL轉換爲指針,該指針已定義好。

明確輸入您pair應該解決這個問題:

tmp.insert(std::pair<std::string, GMProject::GMProjectMemFn>(TIMELINES_IDENT, NULL)); 
+1

但是'std :: pair'沒有一個非'explicit'泛化拷貝構造函數來取得一個任意類型的'std :: pair'並進行成員轉換?因此,只要'int'可轉換爲'GMProjectMemFn','pair '應該可以轉換爲'pair '。 –

+0

是的,你完全正確。 _real_問題是'int const&'不能隱式轉換爲指針。我會糾正我的答案。感謝您指出了這一點! – atkins

0

啊。 NULL可能只定義爲文字0,make_pair推斷此爲整數,並且pair<int,int>不可轉換爲pair<int,GMProjectMemFn>。它通過運算符[]工作,因爲(我猜)隱式轉換從0到GMProjectMemFn

所以,請試着寫make_pair(PATHS_IDENT, (GMProjectMemFn)0)