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

发布于 2024-08-22 08:37:44 字数 931 浏览 4 评论 0原文

我已经声明了一个模板类 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)
}

I've declared a template class MyContainer as bellow, then created an instance of it of type DataType1. The DataType1 class provides a friend function "DataSpecificComparison" which is used by std::sort to compare DataType1 objects. 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.

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.

How can a developer specify that the DataSpecificComparison binary predicate is to take arguments of template type 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)
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

半夏半凉 2024-08-29 08:37:44

您可以使用所需类型的临时本地函数指针变量来选择 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 类型,它解决了歧义。

You can use a temporary local function pointer variable of the required type to select the correct overload of 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.

杀手六號 2024-08-29 08:37:44

sth 已经给出了正确的答案,但还有一个基于相同原理的直接替代方案:

void SortMyContainerObjects()
{

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

这基本上使用相同的机制。强制转换强制重载决策在 std::sort 的模板参数推导之前发生。

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.

鸠书 2024-08-29 08:37:44
template<typename T>
struct DataSpecificComp : public binary_function<T, T, bool>
{
public:
    bool operator()(const T* lhs, const T* rhs)
    {
        return *lhs < *rhs;
    }
};

调用排序函数如下所示:

sort(vi.begin(), vi.end(), DataSpecificComp<int>());
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(vi.begin(), vi.end(), DataSpecificComp<int>());
身边 2024-08-29 08:37:44

我更喜欢以下内容:默认情况下,它将对象与 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>());
}

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

#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>());
}
帅哥哥的热头脑 2024-08-29 08:37:44

您是否尝试将 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>)
}
....

Did you try defining DataSpecificComparison as template with bunch of specializations and giving it the type?

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>)
}
....
凉城凉梦凉人心 2024-08-29 08:37:44

模板化 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);
    }
}

Templating DataSpecificComparison should work. You can also specifically call the proper std::sort template, but it's a bit cumbersome:

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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文