[英]Using STL algorithms (specifically std::sort) from within a templated class
我已经将模板类MyContainer声明为贝娄,然后创建了一个类型为DataType1的实例。 DataType1类提供了友元函数“DataSpecificComparison”,std :: sort使用它来比较DataType1对象。 该程序正确编译和排序。
然后我定义了一个名为DataType2的类,给它一个朋友实现“DataSpecificComparison”并用它来创建另一个MyContainer实例。
我现在无法将程序编译为“ C2914:'std :: sort':无法推断模板参数,因为函数参数不明确 ”报告编译时错误。
开发人员如何指定DataSpecificComparison二进制谓词采用模板类型T *的参数? 或者还有另一种解决这个问题的方法吗?
template <class T>
class MyContainer
{
private:
vector<T*> m_vMyContainerObjects;
....
public:
....
void SortMyContainerObjects()
{
std::sort(m_vMyContainerObjects.begin(), m_vMyContainerObjects.end(), DataSpecificComparison)
}
}
class DataType1
{
....
friend bool DataSpecificComparison(const DataType1 * lhs, const DataType1 * rhs)
}
class DataType2
{
....
friend bool DataSpecificComparison(const DataType2* lhs, const DataType2* rhs)
}
您可以使用所需类型的临时本地函数指针变量来选择DataSpecificComparison
的正确重载:
void SortMyContainerObjects()
{
typedef bool (*comparer_t)(const T*, const T*);
comparer_t cmp = &DataSpecificComparison;
std::sort(m_vMyContainerObjects.begin(), m_vMyContainerObjects.end(), cmp);
}
在这里,编译器可以推断出你想要使用的DataSpecificComparison
的匹配超载comparer_t
类型,它解决了歧义。
......已经给出了正确答案,但也有基于同样原则的直接替代方案:
void SortMyContainerObjects()
{
std::sort(m_vMyContainerObjects.begin(), m_vMyContainerObjects.end(),
static_cast<bool (*comparer_t)(const T*, const T*)>(&DataSpecificComparison));
}
这基本上使用相同的机制。 强制重载决策发生在std::sort
的模板参数演绎之前。
template<typename T>
struct DataSpecificComp : public binary_function<T, T, bool>
{
public:
bool operator()(const T* lhs, const T* rhs)
{
return *lhs < *rhs;
}
};
调用sort函数如下所示:
sort(vi.begin(), vi.end(), DataSpecificComp<int>());
我更喜欢以下几行:默认情况下,它会将对象与less_than
进行比较(因此您不必记住提供一个有趣名称的函数),并且有一个重载允许给出自己的比较函子(同样,值为主):
#include <vector>
#include <algorithm>
#include <functional>
template <class T, class Func>
struct indirect_binary_call_type: public std::binary_function<const T*, const T*, bool>
{
Func f;
indirect_binary_call_type(Func f): f(f) {}
bool operator()(const T* a, const T* b) const
{
return f(*a, *b);
}
};
template <class T, class Func>
indirect_binary_call_type<T, Func> indirect_binary_call(Func f)
{
return indirect_binary_call_type<T, Func>(f);
}
template <class T>
class MyContainer
{
private:
std::vector<T*> m_vMyContainerObjects;
public:
void Sort()
{
Sort(std::less<T>());
}
template <class Func>
void Sort(Func f )
{
std::sort(m_vMyContainerObjects.begin(), m_vMyContainerObjects.end(), indirect_binary_call<T>(f));
}
};
int main()
{
MyContainer<int> m;
m.Sort();
m.Sort(std::greater<int>());
}
您是否尝试将DataSpecificComparison定义为具有一系列特化的模板并为其指定类型?
template<T>
bool DataSpecificComparison(const T* t1, const T* t2)
{
// something non compilable here
}
template<> bool DataSpecificComparison<Data1>(const Data1* t1, const Data1* t2)
{
// return *t1 < *t2;
}
....
void SortMyContainerObjects()
{
std::sort(m_vMyContainerObjects.begin(), m_vMyContainerObjects.end(), DataSpecificComparison<T>)
}
....
模板化DataSpecificComparison应该有效。 你也可以专门调用正确的std::sort
模板,但它有点麻烦:
template <class T>
class MyContainer
{
private:
vector<T*> m_vMyContainerObjects;
typedef bool (*compsT)(T, T);
public:
....
void SortMyContainerObjects()
{
std::sort<std::vector<T*>::iterator, compsT>(m_vMyContainerObjects.begin(), m_vMyContainerObjects.end(), DataSpecificComparison);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.