class 中使用的模板涉及通用比较函数
template used in class involving a generic comparison function
我正在尝试在模板中编写一个 Bheap 和涉及通用比较函数的插入函数。这样做的通常方法是什么?我知道如何在 C 中使用函数指针。但是有没有典型的 C++ 方法可以做到这一点?
有人告诉第一个,class F 可以代表任何函数。但我希望这个函数是一个像 f(T,T) 这样的比较函数。而第二个人说了一些关于仿函数的事情
template <class T, class F>class Bheap
{
public:
Bheap<T>(int allocateSize);
void insert(T value, F f);
void getMax();
private:
int sizeUsed;
int allocateSize;
vector<T> myBheap;
};
仿函数是一种提供一个或多个运算符 () 重载的结构,如果您有多个比较,它是一个选择:
// Having a struct X { K key, V value };
struct Less {
template <typename K, typename V>
operator bool () (const X<K, V>& a, const X<K, V>& b> const {
return a.key < b.key;
}
template <typename K, typename V>
operator bool () (const X<K, V>& a, const K& b> const {
return a.key < b;
}
template <typename K, typename V>
operator bool () (const K& a, const X<K, V>& b> const {
return a < b.key;
}
};
您应该实现 class 和 insert
函数,假设传递的任何参数在参数数量方面都是正确的。如果参数个数不是2个,编译器会提示。
在这些情况下,这是预期的效果。让编译器检测到该函数无效,从而用户必须将函数更改为正确的要求。
使用您的代码的演示如下:
#include <vector>
template <class T, class F>
class Bheap
{
public:
Bheap(int allocateSize) {}
void insert(T value, F f)
{
f(value, value);
}
void getMax();
private:
int sizeUsed;
int allocateSize;
std::vector<T> myBheap;
};
void SomeFunction(int, int)
{}
int main()
{
typedef void (*fn)(int, int);
Bheap<int, fn> b(10);
b.insert(10, SomeFunction);
}
您会看到它可以正确编译和链接(我使用了函数指针,但重载 operator()
的仿函数也足够了)。
现在,如果用户的函数更改为接受 1 个参数的函数,我们将得到不同的场景:
#include <vector>
template <class T, class F>
class Bheap
{
public:
Bheap(int allocateSize) {}
void insert(T value, F f)
{
f(value, value);
}
void getMax();
private:
int sizeUsed;
int allocateSize;
std::vector<T> myBheap;
};
void SomeFunction(int)
{}
int main()
{
typedef void (*fn)(int);
Bheap<int, fn> b(10);
b.insert(10, SomeFunction);
}
无效的函数会使你的class编译失败。由于您的模板需要 2 个参数的函数,因此通过指针传递 1 个参数的函数会导致错误(您可以在此处看到:http://ideone.com/rT7RRa)
对于函数对象,这里是编译成功的例子:
编译失败:
我正在尝试在模板中编写一个 Bheap 和涉及通用比较函数的插入函数。这样做的通常方法是什么?我知道如何在 C 中使用函数指针。但是有没有典型的 C++ 方法可以做到这一点?
有人告诉第一个,class F 可以代表任何函数。但我希望这个函数是一个像 f(T,T) 这样的比较函数。而第二个人说了一些关于仿函数的事情
template <class T, class F>class Bheap
{
public:
Bheap<T>(int allocateSize);
void insert(T value, F f);
void getMax();
private:
int sizeUsed;
int allocateSize;
vector<T> myBheap;
};
仿函数是一种提供一个或多个运算符 () 重载的结构,如果您有多个比较,它是一个选择:
// Having a struct X { K key, V value };
struct Less {
template <typename K, typename V>
operator bool () (const X<K, V>& a, const X<K, V>& b> const {
return a.key < b.key;
}
template <typename K, typename V>
operator bool () (const X<K, V>& a, const K& b> const {
return a.key < b;
}
template <typename K, typename V>
operator bool () (const K& a, const X<K, V>& b> const {
return a < b.key;
}
};
您应该实现 class 和 insert
函数,假设传递的任何参数在参数数量方面都是正确的。如果参数个数不是2个,编译器会提示。
在这些情况下,这是预期的效果。让编译器检测到该函数无效,从而用户必须将函数更改为正确的要求。
使用您的代码的演示如下:
#include <vector>
template <class T, class F>
class Bheap
{
public:
Bheap(int allocateSize) {}
void insert(T value, F f)
{
f(value, value);
}
void getMax();
private:
int sizeUsed;
int allocateSize;
std::vector<T> myBheap;
};
void SomeFunction(int, int)
{}
int main()
{
typedef void (*fn)(int, int);
Bheap<int, fn> b(10);
b.insert(10, SomeFunction);
}
您会看到它可以正确编译和链接(我使用了函数指针,但重载 operator()
的仿函数也足够了)。
现在,如果用户的函数更改为接受 1 个参数的函数,我们将得到不同的场景:
#include <vector>
template <class T, class F>
class Bheap
{
public:
Bheap(int allocateSize) {}
void insert(T value, F f)
{
f(value, value);
}
void getMax();
private:
int sizeUsed;
int allocateSize;
std::vector<T> myBheap;
};
void SomeFunction(int)
{}
int main()
{
typedef void (*fn)(int);
Bheap<int, fn> b(10);
b.insert(10, SomeFunction);
}
无效的函数会使你的class编译失败。由于您的模板需要 2 个参数的函数,因此通过指针传递 1 个参数的函数会导致错误(您可以在此处看到:http://ideone.com/rT7RRa)
对于函数对象,这里是编译成功的例子:
编译失败: