2012-07-07 49 views
4

舉一個簡單的例子。如果我編譯以下main.mm文件沒有ARC,它工作正常。如何使C++模板適用於使用ARC的Objective C類型?

#import <Foundation/Foundation.h> 

template <typename T> 
int testing(const T & whoCares) { 
    return 0; 
} 

int main(int argc, const char * argv[]) 
{ 
    return testing(@"hello"); 
} 

如果我編譯這與ARC,出現以下錯誤:

/Users/sam/Projects/TemplateTest/TemplateTest/main.mm:10:12: error: no matching function for call to 'testing' 
return testing(@"hello"); 
     ^~~~~~~ 
/Users/sam/Projects/TemplateTest/TemplateTest/main.mm:4:5: note: candidate template ignored: substitution failure [with T = NSString *] 
int testing(const T & whoCares) { 
    ^
1 error generated. 

爲什麼?更重要的是,它可以解決嗎?沒有任何進一步的解釋爲什麼替代失敗。如果我明確地通過類型,如下所示:

return testing<NSString *>(@"hello"); 

它的工作原理。說了這麼多,我不想,也不應該在我的代碼中做這件事。

有趣的是,這隻對Objective C類型失敗。以下替換做工精細,無論被啓用ARC的:

return testing("hello"); 
return testing(123); 
+0

你有沒有在您的Xcode版本切換編譯器,如果是這樣,這是否有所作爲的選項? – 2012-07-07 21:21:30

+0

我確實(我正在使用Xcode 4.3.3)。不過,我的印象是,ARC只適用於Apple LLVM Compiler 3.1設置(這是我使用的)。 – SamCee 2012-07-07 22:25:17

+0

您的示例在Clang版本3.2中正常工作。我懷疑@ SamCee的答案是否正確,並且該錯誤已被修復。 – Quuxplusone 2012-10-09 00:07:56

回答

0

除非我失去的Objective-C之間的根本區別++和C++,你總是通過模板的類型。編譯器不會在這一個上做出明智的選擇。您必須聲明該類型。在GCC G ++中,它失敗並顯示以下消息:

hello.cpp: In function ‘int main()’: 
hello.cpp:7: error: ‘t’ was not declared in this scope 

模板不應該像這樣聰明。您必須記住C++是靜態類型的,並且如果非常有限,則輸入推理。在Objective-C中,您可以將任何內容傳遞到id並忘記它。長話短說,即使它編譯,也不應該,也不要依賴C++和Objective-C來混合。 Objective-C++可能是一個強大的組合,但請記住,它們很少能與對方完美搭配。

+1

好了,這不是模板的工作原理。模板類型實際上是爲函數推斷的(不是用於構造函數,但是)。 – 2012-07-07 22:26:59

+0

@JonathanSterling:在哪?從我看到的不在C++中。這給了我一個編譯器錯誤。這是一個Objective-C的東西嗎?或者它是Apple LLVM語言擴展(我使用GCC)。 – Linuxios 2012-07-07 22:40:02

+0

@Linuxios:就* actual * C++(即:不是Objective-C++)而言,模板函數的模板類型可以根據給定的參數類型進行推斷。如果你有一些實際的C++代碼不適用,那可能是因爲你做了其他錯誤或者做出推理是不可能的。 – 2012-07-07 22:45:20

2

不幸的是,它看起來像這可能是一個編譯器錯誤與鐺。

請參見:http://lists.apple.com/archives/objc-language/2012/Feb/msg00078.html

+0

我點擊是爲了回答Linuxios的答案,當時答案是最高的,然後SamCee的答案成爲最高的答案,並且(競賽條件?)我的downvote神祕地從一個轉移到另一個。顯然,SO不會讓你刪除一個意外downvote。 :( – Quuxplusone 2012-10-09 00:09:51

+0

編輯你的答案,以便我可以更改我的投票!如果你有權利的來源聲稱它是在Clang 3.2/Xcode 4中修復的。5(例如Bugzilla ID),將它同時添加到您編輯的答案將是非常好的。 – Quuxplusone 2012-11-14 21:59:10