2012-07-07 51 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