【问题标题】:How to make C++ templates work for Objective C types with ARC?如何使 C++ 模板适用于具有 ARC 的 Objective C 类型?
【发布时间】:2012-07-07 21:09:06
【问题描述】:

举个简单的例子。如果我在没有 ARC 的情况下编译以下 main.mm 文件,它可以正常工作。

#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);

【问题讨论】:

  • 您是否可以选择在您的 Xcode 版本中切换编译器,如果可以,是否会有所不同?
  • 我愿意(我使用的是 Xcode 4.3.3)。但是,我的印象是 ARC 仅适用于 Apple LLVM Compiler 3.1 设置(这是我正在使用的)。
  • 您的示例适用于 Clang 3.2 版。我怀疑@SamCee 的回答是正确的,并且该错误已经修复。
  • @Quuxplusone 是的,你是对的。 Apple 发布 XCode 4.5 时已修复此问题

标签: c++ objective-c automatic-ref-counting clang


【解决方案1】:

不幸的是,这看起来可能是一个带有 clang 的编译器错误。

见:http://lists.apple.com/archives/objc-language/2012/Feb/msg00078.html

【讨论】:

  • 当 Linuxios 的答案是最高答案时,我点击了对它的否决,然后 SamCee 的答案成为最高答案,并且(竞争条件?)我的否决票神秘地从一个转移到另一个。显然,SO不允许您删除意外的否决票。 :(
  • 编辑你的答案,这样我就可以改变我的投票了!如果您有权威来源声称它已在 Clang 3.2 / Xcode 4.5 中得到修复(例如 Bugzilla ID),最好同时将其添加到您编辑的答案中。
【解决方案2】:

除非我遗漏了 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++ 可能是一个强大的组合,但请记住,它们很少能完美地协同工作。

【讨论】:

  • 好吧,模板不是这样工作的。模板类型实际上是为函数推断的(但不是为构造函数)。
  • @JonathanSterling:在什么方面?从我所看到的情况来看,不是在 C++ 中。这给了我一个编译器错误。那是Objective-C的东西吗?或者它是 Apple LLVM 语言扩展(我使用了 GCC)。
  • @Linuxios:就实际 C++(即:不是Objective-C++)而言,模板函数的模板类型可以从给定的参数类型中推断出来,在可能的情况。如果您有一些实际的 C++ 代码不起作用,这可能是因为您做错了其他事情或无法进行推理。
  • @NicolBolas:谢谢。你每天都在 SO 上学到新东西。我总是喜欢在 cmets 中学习这样的小东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-15
  • 1970-01-01
  • 2021-12-08
  • 2021-06-03
  • 2017-11-15
相关资源
最近更新 更多