开发者

syntax help required on templated static member function

I have a bunch of containers of object pointers that I want to iterate through in different contexts to produce diagnostics for them. I'm struggling with the syntax required to define the functions... which, on account of these objects filtering through diverse parts of my application, seem best encapsulated in a dedicated diagnostics class thus:

// Code sketch only - detail fleshed out below...  
class ObjectListDiagnoser  
{  
public:  
    static void GenerateDiagnostics( /* help required here! */ );  
};  

...

// Elsewhere in the system...  
ObjectListDiagnoser::GenerateDiagnostics( /* help required here! */ );  

What I'd like to be able to do (in places across my application) is at least this:

std::vector<MyObject *> objGroup1;  
std::list<MyObject *> objGroup2;

ObjectListDiagnoser::GenerateDiagnostics( objGroup1.begin(), objGroup1.end() );  
ObjectListDiagnoser::GenerateDiagnostics( objGroup2.begin(), objGroup2.end() );  
ObjectListDiagnoser::GenerateDiagnostics( objGroup1.rbegin(), objGroup1.rend() );  

I have tried to template my function in two ways, with no success:

class ObjectListDiagnoser  
{  
public:  
    // 1 - nope.  
    template <class ObjIter>
    static void GenerateDiagnostics( ObjIter first, ObjIter last );  
    // 2. - nope.  
    template <class Container, class ObjIter>
    static void GenerateDiagnostics( Container<MyObject *>::ObjIter first,  
                                     Container<MyObject *>::ObjIter last );  
};  

Can someone provide the correct syntax for this? The container type will vary, and the direction of iteration will vary, but always for the same type of object.


Summary of discussion in the comments开发者_如何学C below - case 1 is correct... but leads to a broadly unintelligible linker error if the template function definition is not in the header. template function definitions simply have to go in the header - a point easily forgotten. Slip it into the header, and all is well - compiles, links... and hopefully even runs.


You should use option 1. As with the functions in <algorithm>, container types don't belong in template arguments.

We'll need more information about what's going wrong. You should be OK… you just need to add the definition.

template <class ObjIter>
static void ObjectListDiagnoser::GenerateDiagnostics
 ( ObjIter first, ObjIter last ) {
   …
}

EDIT: as with all templates, this definition needs to go in the header file. Using a template outside the source file it's defined in is widely unsupported.

You can use explicit instantiation, which allows implementation in a non-header file but negates some of the benefits of using templates: you can only use the template parameters which were explicitly instantiated.

// implementation in source file

template <class ObjIter>
static void ObjectListDiagnoser::GenerateDiagnostics
 ( ObjIter first, ObjIter last ) {
   …
}

template void ObjectListDiagnoser::GenerateDiagnostics
  < std::list<Object>::iterator >
 ( std::list<Object>::iterator first, std::list<Object>::iterator last );

template void ObjectListDiagnoser::GenerateDiagnostics
  < std::vector<Object>::iterator >
 ( std::vector<Object>::iterator first, std::vector<Object>::iterator last );

// now you can only use vector<Object>::iterator or list<Object>::iterator
// as arguments.


I agree with @sth that there is no problem with 1. Infact that is how STL algorithms are declared refer - find

If 1 works there is no need for 2. Any ways its declaration should be

template <class Container>
static void GenerateDiagnostics( typename Container<MyObject *>::iterator first, 
       typename Container<MyObject *>::iterator last );  

Please note - this is just an example which would work with iterator of a container and may not work with its reverse_iterator or const_iterator

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜