简体   繁体   English

模板化函数指针,这可能吗?

[英]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. 编辑:@ James,这是const类成员函数模板的声明。 The function takes the following arguments 该函数采用以下参数

1) an unsigned int 1)一个无符号的int

2) a priority_queue, sorted in an arbitrary manner specified by the client 2)priority_queue,以客户端指定的任意方式排序

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. std::priority_queue需要一个函数类(如less <>,它已定义了operator()),而不是C样式的函数指针。

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. 其中T是比较器类型。

Is Traverse a stand alone function ? Traverse是独立功能吗? If yes then you should remove const in the very end. 如果是,则应在最后删除const It compiles with that change. 它随着这种变化而编译。 Also change (*T) to simply (*) . 同样将(*T)更改为(*)

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. priority_queue接受compare参数的函数指针,但是您必须将函数指针传递给构造函数,而不是模板。 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). 简而言之,模板在这里几乎没有用,因为函数不是类型,而比较函数的类型是100%预定的(它是MyQueue)。 The compiler wouldn't have any information to infer a specific type from the arguments passed to Traverse(). 编译器将没有任何信息可以从传递给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. 只需将T作为第三个模板参数传递给您的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. 仍然存在std::priority_queue不是类型的问题,因此您不能使用它声明函数。 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; 毫无疑问,可以尝试将Q限制为priority_queue一组实例化,但这将是棘手的。 you'll probably need some sort of template wrapper class with template template parameters and partial specialization. 您可能需要某种带有模板模板参数和部分特化功能的模板包装器类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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