简体   繁体   English

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

[英]Using STL algorithms (specifically std::sort) from within a templated class

I've declared a template class MyContainer as bellow, then created an instance of it of type DataType1. 我已经将模板类MyContainer声明为贝娄,然后创建了一个类型为DataType1的实例。 The DataType1 class provides a friend function "DataSpecificComparison" which is used by std::sort to compare DataType1 objects. DataType1类提供了友元函数“DataSpecificComparison”,std :: sort使用它来比较DataType1对象。 The program compiled and sorted correctly. 该程序正确编译和排序。

I then defined a class called DataType2, gave it a friend implementation of "DataSpecificComparison" and used it to create another instance of MyContainer. 然后我定义了一个名为DataType2的类,给它一个朋友实现“DataSpecificComparison”并用它来创建另一个MyContainer实例。

I am now unable to compile the program as a " C2914: 'std::sort' : cannot deduce template argument as function argument is ambiguous " compile time error is reported. 我现在无法将程序编译为“ C2914:'std :: sort':无法推断模板参数,因为函数参数不明确 ”报告编译时错误。

How can a developer specify that the DataSpecificComparison binary predicate is to take arguments of template type T*? 开发人员如何指定DataSpecificComparison二进制谓词采用模板类型T *的参数? Or is there another way around this issue? 或者还有另一种解决这个问题的方法吗?

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

You can use a temporary local function pointer variable of the required type to select the correct overload of DataSpecificComparison : 您可以使用所需类型的临时本地函数指针变量来选择DataSpecificComparison的正确重载:

void SortMyContainerObjects()
{
    typedef bool (*comparer_t)(const T*, const T*);
    comparer_t cmp = &DataSpecificComparison;
    std::sort(m_vMyContainerObjects.begin(), m_vMyContainerObjects.end(), cmp);
}

Here the compiler can deduce that you want to use the DataSpecificComparison overload that matches the comparer_t type, which resolves the ambiguity. 在这里,编译器可以推断出你想要使用的DataSpecificComparison的匹配超载comparer_t类型,它解决了歧义。

sth already gave a correct answer, but there's also a direct alternative based on the same principle: ......已经给出了正确答案,但也有基于同样原则的直接替代方案:

void SortMyContainerObjects()
{

    std::sort(m_vMyContainerObjects.begin(), m_vMyContainerObjects.end(),
       static_cast<bool (*comparer_t)(const T*, const T*)>(&DataSpecificComparison));
}

This uses essentially the same mechanism. 这基本上使用相同的机制。 The cast forces overload resolution to happen before the Template Argument Deduction for std::sort . 强制重载决策发生在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;
    }
};

call the sort function as shown below: 调用sort函数如下所示:

sort(vi.begin(), vi.end(), DataSpecificComp<int>());

I'd prefer something along the following lines: by default it compares objects with less_than (so you wouldn't have to remember to provide a function with a funny name), and there's an overload that allows giving your own comparison functor (again, value-based): 我更喜欢以下几行:默认情况下,它会将对象与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>());
}

Did you try defining DataSpecificComparison as template with bunch of specializations and giving it the type? 您是否尝试将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>)
}
....

Templating DataSpecificComparison should work. 模板化DataSpecificComparison应该有效。 You can also specifically call the proper std::sort template, but it's a bit cumbersome: 你也可以专门调用正确的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.

相关问题 在模板化类中将`std :: sort`与成员函数一起使用 - Using `std::sort` with a member function in a templated class 在STL算法中使用模板化谓词的问题 - Problem using templated predicate in STL algorithms 如何使用标准stl算法从istream填充std :: vector - how to fill std::vector from istream using standard stl algorithms 以模板函数为参数的STL算法 - STL algorithms with templated functions as parameter 在dll中定义模板化类的排序方法(使用std :: sort进行排序),然后从另一个项目中调用它 - Define sorting method ( that use std::sort for sorting) of a templated class in dll and calling it from another project 排序std :: vector <myclass> 使用STL的排序功能在一排 - Sort std::vector<myclass> in one line using sort function from STL 在模板化 class 的方法上使用 std::enable_if - using std::enable_if on a method of a templated class C++ STL:使用派生的虚拟 class 作为 std::sort() 的“严格弱排序” - C++ STL: Using derived virtual class as “Strict Weak Ordering” for std::sort() 在std:sort()上使用类 - Using class on std:sort() 在不同的STL实现中,C ++ 11 std :: sort中使用了哪些算法? - What algorithms are used in C++11 std::sort in different STL implementations?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM