C++ 在模板类中使用STL算法(特别是std::sort)

C++ 在模板类中使用STL算法(特别是std::sort),c++,templates,stl,sorting,C++,Templates,Stl,Sorting,我声明了一个模板类MyContainer,如下所示,然后创建了一个DataType1类型的实例。DataType1类提供了一个友元函数“DataSpecificComparison”,std::sort使用该函数来比较DataType1对象。程序编译和排序正确 然后我定义了一个名为DataType2的类,给了它一个“DataSpecificComparison”的friend实现,并用它创建了MyContainer的另一个实例 我现在无法将程序编译为“C2914:'std::sort”:无法推断

我声明了一个模板类MyContainer,如下所示,然后创建了一个DataType1类型的实例。DataType1类提供了一个友元函数“DataSpecificComparison”,std::sort使用该函数来比较DataType1对象。程序编译和排序正确

然后我定义了一个名为DataType2的类,给了它一个“DataSpecificComparison”的friend实现,并用它创建了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)
}
模板
类霉菌容器
{
私人:
向量m_vmy容器对象;
....
公众:
....
void SortMyContainerObjects()
{
std::sort(m_-vMyContainerObjects.begin()、m_-vMyContainerObjects.end()、DataSpecificComparison)
}
}
类数据类型1
{
....
friend bool数据规格比较(常数数据类型1*lhs,常数数据类型1*rhs)
}
类数据类型2
{
....
friend bool数据规格比较(常数数据类型2*lhs,常数数据类型2*rhs)
}

您是否尝试将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>)
}
....
模板
布尔数据规格比较(常数T*t1,常数T*t2)
{
//这里有些不可编译的东西
}
模板布尔数据规格比较(常数数据1*t1,常数数据1*t2)
{
//返回*t1<*t2;
}
....
void SortMyContainerObjects()
{
std::sort(m_-vMyContainerObjects.begin()、m_-vMyContainerObjects.end()、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);
    }
}
模板
类霉菌容器
{
私人:
向量m_vmy容器对象;
类型定义布尔(*compsT)(T,T);
公众:
....
void SortMyContainerObjects()
{
std::sort(m_-vMyContainerObjects.begin()、m_-vMyContainerObjects.end()、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
重载,这可以解决歧义。

模板
template<typename T>
struct DataSpecificComp : public binary_function<T, T, bool>
{
public:
    bool operator()(const T* lhs, const T* rhs)
    {
        return *lhs < *rhs;
    }
};
struct DataSpecificComp:公共二进制函数 { 公众: 布尔运算符()(常数T*lhs,常数T*rhs) { 返回*左侧<*右侧; } };
调用排序函数,如下所示:

sort(vi.begin(), vi.end(), DataSpecificComp<int>());
排序(vi.begin()、vi.end()、DataSpecificComp());
某事物已经给出了正确的答案,但基于同样的原则,还有一个直接的替代方案:

void SortMyContainerObjects()
{

    std::sort(m_vMyContainerObjects.begin(), m_vMyContainerObjects.end(),
       static_cast<bool (*comparer_t)(const T*, const T*)>(&DataSpecificComparison));
}
void SortMyContainerObjects()
{
std::sort(m_-vMyContainerObjects.begin(),m_-vMyContainerObjects.end(),
静态(数据规格比较);
}

这使用了基本相同的机制。强制转换强制重载解析发生在
std::sort

的模板参数推断之前。我更喜欢以下内容:默认情况下,它将对象与
小于
的对象进行比较(因此您不必记得提供具有有趣名称的函数),还有一个重载,允许您给出自己的比较函子(同样,基于值):

#包括
#包括
#包括
模板
结构间接二进制调用类型:公共std::二进制函数
{
函数f;
间接二进制调用类型(Func f):f(f){
布尔运算符()(常数T*a,常数T*b)常数
{
返回f(*a,*b);
} 
};
模板
间接二进制调用类型间接二进制调用(Func f)
{
返回间接二进制调用类型(f);
}
模板
类霉菌容器
{
私人:
std::向量m_vmy容器对象;
公众:
空排序()
{
排序(std::less());
}
模板
无效排序(Func f)
{
std::sort(m_-vMyContainerObjects.begin()、m_-vMyContainerObjects.end()、间接二进制调用(f));
}
};
int main()
{
霉素A;
m、 排序();
m、 排序(std::greater());
}

可能是因为您使用的是指针向量?只是一个猜测。当我只定义MyContainer时,它的朋友函数“DataSpecificComparison”被编译并运行。在定义DataType2并创建MyContainer实例时,发生了此错误。顺便说一句——我第一次尝试这个解决方案涉及使用std::sort,但没有实现用户定义的二进制谓词——我只是重载了默认值小于(非常好,这对于我上面描述的应用程序来说是正确的。这个解决方案对typedef语句进行了一些调整:typedef bool(compsT)(const T,const T*);
#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>());
}