views:

118

answers:

2

I wrote code that looked like the following:

template<typename CocoaWidget>
class Widget : boost::noncopyable
{
private:
  CocoaWidget* mCocoaWidget;

public:
  Widget()
  {
    mCocoaWidget = [[CocoaWidget alloc] init];
  }

  // ...
};

class Button : Widget<NSButton>
{
  // ...
};

But that doesn't work, because Mac Dev Center says:

Objective-C classes, protocols, and categories cannot be declared inside a C++ template

So what shall I do now best?

+5  A: 

Are you sure you can't do this (have you tried)?

The quote from Mac Dev Center says you can't declare an Objective-C class inside a template. What you're doing, however, is merely declaring a pointer to an Objective-C object inside a template -- quite a different thing, and I don't see a reason why it shouldn't be allowed (though I have never tried).

Martin B
I think, you are right. I tested the simplified example and it compiles. I just got `invalid use of incomplete type ‘class widget<NSButton>’` so i thought that would be the problem. So probably the mistake is anywhere else. Thanks though!
Polybos
@Niels: If you get that error message, the problem is probably that you aren't including the header file with the definition of your `Widget<CocoaWidget>` template class.
Martin B
No. I just forgot anywhere a closing bracket. I've solved it no (Why can't gcc just say that I forgot a closing }???
Polybos
@Niels: That's typical of gcc, unfortunately. Clang (clang.llvm.org) will hopefully fix this...
Martin B
A: 

What's wrong? Your code is working. My similar test case compiled and run without leaks.

#import <Foundation/Foundation.h>

template <typename T>
class U {
protected:
        T* a;
public:
        U() { a = [[T alloc] init]; }
        ~U() { [a release]; }
};

class V : U<NSMutableString> {
public:
        V(int i) : U<NSMutableString>() { [a appendFormat:@"%d = 0x%x\n", i, i]; }
        void print() const { NSLog(@"%@", a); }
};

int main() {
        U<NSAutoreleasePool> p;
        V s(16);
        s.print();
        return 0;
}
KennyTM