2009-12-16 77 views
2

我現在有一個函數模板,引用以參考的,但這東西在本質上等同於:處理的C++模板

template <typename T> 
void f(T& t) 
{ 
    t = T(); 
} 

現在,我可以打電話:

int a; 
f(a); 

初始化我的變量a。 我甚至可以這樣做:

std::vector<int> a(10); 
f(a[5]); 

然而,這將失敗:

std::vector<bool> a(10); 
f(a[5]); 

的原因是a[5]返回參考語義對象,而不是引用。所以,我需要能夠寫:

template <typename T> 
void f(T a) 
{ 
    a = T(); 
} 

但如果我加入這個新的模板,並嘗試編譯第一個例子(與INT),我得到了以下錯誤:

test_multi_tmpl.cc: In function ‘int main()’: 
test_multi_tmpl.cc:20: error: call of overloaded ‘f(int&)’ is ambiguous 
test_multi_tmpl.cc:6: note: candidates are: void f(T&) [with T = int] 
test_multi_tmpl.cc:12: note:     void f(T) [with T = int] 

任何想法如何解決這個問題?我不想超載f只爲std::vector<bool>::reference,因爲這個構造可能出現在其他地方...

回答

4

我認爲專門爲std::vector<bool>::reference f是唯一的選擇。

注意,使用std::vector<bool>可能是擺在首位一個壞主意(在std::vector<bool>專業化已經廢棄了C++語言的未來版本),所以你可以只使用std::deque<bool>代替。

+0

'vector '也可能工作。 – 2009-12-16 19:01:31

+1

'vector '技術上會更接近。 – 2009-12-16 19:11:33

+0

專精'std :: vector '確實被棄用,但爲什麼要停止使用布爾值向量呢? – 2009-12-16 19:16:49

0

使用特徵或模板專業化將使它工作。

+0

我認爲他希望它適用於任何「參考類型」,而不僅僅是專門用於「矢量 :: reference」。你會在這裏使用什麼特質? – 2009-12-16 19:19:20

1

有兩種方法可以做到這一點,其中一種方法,正如您所建議的,專門針對std::vector<bool>::reference。另一種是使用類型特徵分派。

template <class T> 
void f (T& t) { 
    f_impl(t, is_reference_wrapper_type<T>()); 
} 

template <class T> 
void f_impl(T& t, mpi::false_) { 
    t = T(); 
} 

template <class T> 
void f_impl(T& t, mpi::true_) { 
    // do nothing, or voodoo here 
} 

注意上面的代碼是未測試,會有調度;基於性狀的更復雜的裝置 - 或一組性狀 - 在這種情況下。

這也意味着你需要實現is_reference_wrapper_type像這樣:

template <class T> 
struct is_reference_wrapper_type : mpi::false_ {}; 

template <> 
struct is_reference_wrapper_type<std::vector<bool>::reference> : mpi::true_ {}; 
+0

如果我調用'int a;那麼這與你的代碼無關, f(a);',那永遠不會使用a作爲參考。 – PierreBdR 2009-12-16 19:37:42

+0

哦,你是對的。讓我編輯來解決它。 – 2009-12-16 19:42:41

+0

mmmhh ...實際上,這並沒有解決問題!這仍然不允許:矢量 a(10); F(A [5]); – PierreBdR 2009-12-17 12:06:28

1

我不知道你是否已經知道這個...

專業化的std ::矢量不是真的是STL容器,因爲它確實不是符合必要的要求。特別是,由於引用語義(不能僞造引用),不可能創建滿足STL concepts的代理容器。查詢this article瞭解更多信息。 (此外,如Autopulated提及應該有一個編譯器指令以提供對標準::在未來C++標準矢量控制。)

,可以幫助解決問題的簡單的解決方法是通過用於這種特殊類型的過載功能˚F (和其他人,如果他們出現,並不是很多)。請注意,這是一個過載而不是專業化。你可能也想檢查這個why not specialize function templates


void f(std::vector<bool>::reference t) 
{ 
    /* ... */ 
} 
+0

我知道我可能會超載。但正如我所說,我想*不*這樣做。首先,這隻適用於這個特定的情況,而且,這不是一個真正的功能,而是我的情況。所以我不能在班上有所有可能的方法。 – PierreBdR 2009-12-16 20:01:52