简体   繁体   中英

How to make C++ templates work for Objective C types with ARC?

Take a trivial example. If I compile the following main.mm file without ARC, it works fine.

#import <Foundation/Foundation.h>

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

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

If I compile this with ARC, the following error occurs:

/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.

Why? And more importantly, can it be worked around? There isn't any further explanation for why the substitution fails. If I explicitly pass the type, like so:

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

it works. Having said that, I don't want to, and shouldn't have to do this all over my code.

What's also interesting is this only fails for Objective C types. The following substitutions work fine regardless of ARC being enabled:

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

Unfortunately, it looks like this is possibly a compiler bug with clang.

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

Unless I'm missing a fundamental difference between Objective-C++ and C++, you ALWAYS pass the type of the template. The compiler doesn't try to be smart on this one. You must declare the type. In GCC G++, it fails with this message:

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

Templates aren't supposed to be smart like that. You have to remember that C++ is statically typed, and type inference if very limited. In Objective-C, you can pass anything into an id and forget about it. Long story short, even if it does compile, it shouldn't, and don't depend on C++ and Objective-C to mix well. Objective-C++ may be a powerful combination, but remember that they will rarely work flawlessly with each other.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM