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

时间:2011-04-14 14:11:03

标签: c++

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;

上面的代码基本上没有编译。我认为它的语法错误与以下行:

    bool(*T)(const unsigned&, const unsigned&) 

正确的语法是什么?

感谢。

编辑: @ 詹姆士, 这是const类成员函数模板的声明。 该函数采用以下参数

1)unsigned int

2)priority_queue,以客户端指定的任意方式排序

该函数返回无符号整数的向量。

5 个答案:

答案 0 :(得分:4)

试试这个:

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;

答案 1 :(得分:1)

为什么需要函数指针作为模板参数? std::priority_queue需要一个函数类(比较少&lt;&gt;定义了operator()),而不是C风格的函数指针。

即使没有模板参数,以下代码也不起作用:

bool(*fn)(const unsigned&, const unsigned&) = 0;

std::priority_queue<std::pair<unsigned, unsigned>,
    std::vector<std::pair<unsigned, unsigned>>, fn> q;

你需要做什么,是Rob建议的:

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;

其中T是Comparer类型。

答案 2 :(得分:1)

Traverse是一个独立的功能吗?如果是,那么您应该在最后删除const。它汇编了这种变化。同时将(*T)更改为(*)

如果它是一个类的成员,那么它也应该编译。

答案 3 :(得分:1)

Derived from here

priority_queue接受compare参数的函数指针,但是您必须将函数指针传递给构造函数,而不是模板。模板只接受函数指针的类型。

实现这个的最简单方法是使用一个仿函数(函数对象,谓词类或者你命名它)。

从该仿函数中,您还可以调用函数指针,前提是它在编译时是全局已知的。但我认为并非如此,你可能不得不在构造函数的路径中使用'传递函数指针'。

如果在编译时知道函数地址:

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;

如果不是:

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);
}

简而言之,模板在这里几乎没用,因为函数不是类型,比较函数的类型是100%预定的(它是MyQueue)。编译器没有任何信息可以从传递给Traverse()的参数中推断出特定的类型。

如果您实际上并不需要在运行时动态更改比较函数,那么此处的其他答案是可行的方法。只需将T作为第三个模板参数传递给priority_queue。

答案 4 :(得分:0)

您的编辑有帮助。仍有问题 std::priority_queue不是类型,因此您无法声明 使用它的功能。但既然你已经有了模板, 最简单的解决方案是:

template<typename T, typename Q>
std::vector<unsigned>
Travers( unsigned start_node, Q& pQueue ) const;

尝试将Q限制为一组实例化 毫无疑问可以priority_queue,但它会很棘手; 你可能需要某种模板包装类 模板模板参数和部分专业化。