templated function pointer, is this possible?
template<typename T>
std::vector<unsigned>
Traverse
(
unsigned start_node,
std::priority_queue
<
std::pair< unsigned, unsigned >,
std::vector< std::pair<unsigned, unsigned> >,
bool(*T)(const unsigned&, const unsigned&)
> &pQueue
) const;
The above code basically doesnt compile. I think its syntax error with the following line:
bool(*T)(const unsigned&, const unsigned&)
What is the correct syntax?
Thanks.
edit: @ James, This is the declaration of a const class member function template. The function takes the following arguments
1) an unsigned int
2) a priority_queue, sorted in an arbitrary manner specified by the cli开发者_运维技巧ent
The function returns a vector of unsigned ints.
Try this:
template<typename T>
std::vector<unsigned>
Traverse
(
unsigned start_node,
std::priority_queue
<
std::pair< unsigned, unsigned >,
std::vector< std::pair<unsigned, unsigned> >,
T
> &pQueue
) const;
Why would you need a function pointer as a template argument? std::priority_queue
expects a function class (like less<> that has an operator() defined), not a C-style function pointer.
The following code will not work, even without a template argument:
bool(*fn)(const unsigned&, const unsigned&) = 0;
std::priority_queue<std::pair<unsigned, unsigned>,
std::vector<std::pair<unsigned, unsigned>>, fn> q;
What you need to do, is what Rob has suggested:
template<typename T>
std::vector<unsigned>
Traverse
(
unsigned start_node,
std::priority_queue
<
std::pair< unsigned, unsigned >,
std::vector< std::pair<unsigned, unsigned> >,
T
> &pQueue
) const;
Where T is the Comparer type.
Is Traverse
a stand alone function ? If yes then you should remove const
in the very end. It compiles with that change. Also change (*T)
to simply (*)
.
If it's a member of a class then also it should compile.
Derived from here.
priority_queue accepts a function pointer for the compare argument, but you'd have to pass the function pointer to the constructor, not the template. The template would just accept the type of the function pointer.
The easiest way to implement this would be to use a functor (function object, predicate class or however you name it).
From that functor, you could also call the function pointer, provided it is known globally at compile time. But I assume it isn't so you might have to go the 'pass function pointer in constructor' route after all.
If the function address is known at compile time:
typedef bool (*MyFuncPtr)(const unsigned&, const unsigned&);
MyFuncPtr globalPtr = myCompareFunction;
struct MyCompare {
bool operator()(const unsigned &a, const unsigned &b) const {
return globalPtr(a, b);
}
};
std::vector<unsigned>
Traverse
(
unsigned start_node,
std::priority_queue
<
std::pair< unsigned, unsigned >,
std::vector< std::pair<unsigned, unsigned> >,
MyCompare
> &pQueue
) const;
If it isn't:
typedef bool (*MyFuncPtr)(const unsigned&, const unsigned&);
typedef std::priority_queue
<
std::pair< unsigned, unsigned >,
std::vector< std::pair<unsigned, unsigned> >,
MyFuncPtr
> MyQueue;
std::vector<unsigned>
Traverse
(
unsigned start_node,
MyQueue &pQueue
) const;
int main() {
MyQueue queue(myCompareFunction);
Traverse(..., queue);
}
In short, the template is pretty much useless here, because a function is not a type, and the type of the compare function is 100% predetermined (it's MyQueue). The compiler wouldn't have any information to infer a specific type from the arguments passed to Traverse().
If you don't actually need to change the comparison function dynamically during runtime, the other answers here are the way to go. Just pass T as the third template argument to your priority_queue.
Your edit helps some. There's still the problem that
std::priority_queue
isn't a type, so you can't declare
a function using it. But since you've already got a template,
the simplest solution would be:
template<typename T, typename Q>
std::vector<unsigned>
Travers( unsigned start_node, Q& pQueue ) const;
Trying to restrict Q
to a set of instantiations of
priority_queue
can doubtlessly be done, but it will be tricky;
you'll probably need some sort of template wrapper class with
template template parameters and partial specialization.
精彩评论