0

I want to make a generic Array function. In my API, I have generic container that I need to cast to the right class, but I want to make it generic

template<class T>
void UT::printArray(CCArray* arr, T type)
{
    CCObject *aIt = NULL;  
    CCARRAY_FOREACH(arr,aIt )
    {
        T *aElm = static_cast<T*>(aIt );
        int col = aElm ->getColNum(); 
        int row = aElm ->getRowNum();
        CCLOG("col:%d row:%d",col,row);
    }
}

This does not compile right, and also I need to make new T object each time I call this function. What is the right way for this?

Saksham
  • 9,037
  • 7
  • 45
  • 73
user63898
  • 29,839
  • 85
  • 272
  • 514

1 Answers1

2

Of course I don't know what your CCArray is but I can modify your function:

template<class T>
void UT::printArray(CCArray* arr)
{
    CCObject *aIt = NULL;  
    CCARRAY_FOREACH(arr,aIt )
    {
        T *aElm = static_cast<T*>(aIt );
        int col = aElm ->getColNum(); 
        int row = aElm ->getRowNum();
        CCLOG("col:%d row:%d",col,row);
    }
}

I've removed your second T type argument. You'd invoke this as printArray<myType>(arr) explicitly rather than having T inferred from your (unused) argument.

As someone said in a comment your best solution would be to read about iterators and make your CCArray return a proper begin() and end() and then you could use many standard algorithms (e.g. sort) against your container.

Ben Jackson
  • 90,079
  • 9
  • 98
  • 150
  • Just FYI, its a cocos2d thing. The [CCArray](http://www.cocos2d-x.org/reference/native-cpp/V2.1.4/d9/d2e/classcocos2d_1_1_c_c_array.html) concept is part of their toolkit, and no, much to the chagrin of many, the iterator idiom was not part of there mission statement (apparently). – WhozCraig Sep 03 '13 at 05:16
  • @WhozCraig: You can still implement and use iterators even if you can't make new members of `CCArray`. Just define `begin(CCArray *)` and `end(CCArray *)` to return objects of a new `MyCCArrayIterator` type. That class has a reference to the array and internal state to access it. Its `operator *` defers to an accessor in the referenced array. – Ben Jackson Sep 03 '13 at 05:29
  • Thanks , how should be the header statement of this function ? – user63898 Sep 03 '13 at 05:31
  • it gives me linking errors: error LNK2019: unresolved external symbol "public: void __thiscall UT::printArray(class cocos2d::CCArray *)" (??$printArray@VGem@@@UT@@QAEXPAVCCArray@cocos2d@@@Z) referenced in function "public: void __thiscall GameController::FillGemsFromAboveHorizontal(class cocos2d::CCArray *)" (?FillGemsFromAboveHorizontal@GameController@@QAEXPAVCCArray@cocos2d@@@Z) 1>D:\dev\test.win32.exe : fatal error LNK1120: 1 unresolved externals – user63898 Sep 03 '13 at 05:37
  • @user63898 that is a template. it belongs in a header file as-written. *Use* it in a cpp file, but *put* it in the header. ([read this if that confuses you](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file)). – WhozCraig Sep 03 '13 at 05:53
  • @user63898: Did you put the template function in a header and include it from the file that has `FillGemsFromAboveHorizontal`? A template function is sort of like a macro -- the whole definition must be in scope so the compiler can sub in your type and compile it that way. – Ben Jackson Sep 03 '13 at 05:53
  • Thanks for taking the time to answer! – user63898 Sep 03 '13 at 05:58