簡單的回答:使typedef公開。
這會泄漏實現的一個小細節(實際的內部類型),但是因爲它是typedefed,你可以在任何時候重新定義它,它應該沒問題。
簡單一點:交友助手功能,提供訪問您的內部類型。
第二種方法的問題在於,您不僅授予對typedef的訪問權限,還授予對您班級的所有私有部分的訪問權限,這可能不是最好的主意。無論如何,因爲這是一個內部幫助函數,所以它是在你自己的控制之下的,它應該沒問題。 (現在我想起來了,你可能想聲明函數在一個命名的命名空間中,以使friend
聲明成功)
更簡單:在實現文件中創建一個單獨的typedef,並確保它們是同步的。
您可以確保類型與一小段元編程相同,same_type<T,U>
模板將提供一個true
值(如果兩個類型相同,否則爲false)。如果typedef只在一個地方更改,則靜態聲明將觸發錯誤
返回簡單:提供typedef或直接使用類型,而不使用靜態聲明。
你正在調用一個函數(這不應該是你的代碼中的模板),並傳遞一個引用。如果typedef在類中發生更改,則調用將失敗,編譯器會告訴您。
我會去的最後一個選項,雖然它可能看起來有點粗糙,少細膩比別人,但事實是,這是唯一沒有被其他人一個實現細節,你完全控制之下的代碼和好,簡單就更好。
編輯,之後的評論。
我開始寫這個作爲評論,但它變得太長了,所以我將它添加到答案。
這個解決方案本身並沒有什麼錯,除了不必要的做一個通用函數,以後一些錯誤信息可能不會像使用非通用簽名那樣簡單。請注意,template
將而不是公開typedef
(問題標題建議),而是它會使編譯器推斷在調用的地方的類型。
如果更改typedef
,而不是得到一個錯誤,指出該參數helperFn
不能對現有的功能相匹配,則類型推斷,功能匹配,但你會在helperFn
得到一個錯誤更深,如果你使用不再存在的類型的屬性。或者更糟糕的是,如果這種類型的語義發生了變化,那麼您甚至可能不會收到錯誤。
認爲typedef的是std::list<X>
的,而且在你迭代它與這個簡單的正確的for循環的功能:
for (typename T::iterator it=x.begin(), end=x.end(); it != end;) {
if (condition(*it))
it = x.erase(it);
else
++it;
}
你能趕上改變的typedef std::vector<X>
就會有效果?即使代碼現在不正確,編譯器也不能。是否這樣寫for for循環是一個好主意,或者爲什麼它不僅僅使用擦除 - 刪除成語是不同的問題(事實上,前一個循環是可以說是更好的比擦除刪除一個列表),具體情況是語義已經改變,並且因爲類型在語法上與前一個兼容,所以兼容編譯器不會注意到代碼是錯誤的,它不會指向你的那個函數,並且機會是你不會審查/重寫它。
爲什麼不把輔助函數的Foo'的私有成員'?你認爲採取這種方法會失去什麼? – ildjarn 2011-03-30 20:28:48
準確地說,模板將* not *暴露'typedef',而是讓編譯器在調用的地方解析類型。 – 2011-03-31 07:41:01
@dribeas,謝謝。這似乎有點奇怪,類型可以隱式地(由編譯器)解決,但不是明確地(由我)解決。 – criddell 2011-04-01 13:02:15