Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;ORDER BY在结构上的实现_C++_Sorting_Boost_Stl_Compare - Fatal编程技术网

C++ C++;ORDER BY在结构上的实现

C++ C++;ORDER BY在结构上的实现,c++,sorting,boost,stl,compare,C++,Sorting,Boost,Stl,Compare,我在这里和其他网站上搜索了很多,但没有找到令人满意的东西 我需要的是一个非常简单的任务——基本上由C++中的运算符构造顺序。这意味着我有一个包含许多不同数据类型成员的struct,我需要一个比较器来配置它的成员和顺序。以下是我的伪代码想法: comparator.add(&MyStruct::member1, std::less); comparator.add(&MyStruct::member2, std::greater); std::sort(my_vector.begi

我在这里和其他网站上搜索了很多,但没有找到令人满意的东西

我需要的是一个非常简单的任务——基本上由C++中的运算符构造顺序。这意味着我有一个包含许多不同数据类型成员的struct,我需要一个比较器来配置它的成员和顺序。以下是我的伪代码想法:

comparator.add(&MyStruct::member1, std::less);
comparator.add(&MyStruct::member2, std::greater);
std::sort(my_vector.begin(), my_vector.end(), comparator);
我得到按member1排序的数据,如果它等于member2,则由member2决定,依此类推

我不太擅长stl和模板,但我可以阅读和破译一些代码,并发现这是非常合适的解决方案:

遗憾的是,在我的工作中,我必须使用C++ Builder,而错误的32位编译器拒绝编译这个正确的代码。是的,它有boost 1.39可用

有没有人有任何解决方案可以在我的资源可用的情况下为我工作?先谢谢你

编辑:
我得到了非常专业的解决方案,使用了我所知道的硬编写的比较运算符,但在这里效果不太好。我的问题中没有提到这一点。我的结构至少有15个成员,正如我所写的,我需要经常更改成员/列(asc、desc)的单独排序方向。同样,我需要经常更改已排序成员集,就像sql中的order by运算符一样。此外,我不能使用稳定排序之类的东西,因为我只是在为某个类的OnCompare事件之类的东西编写比较器。

为什么不使用一个专门的比较器函数,它首先检查
成员1
,如果相等,则检查
成员2

bool比较器(const-MyStruct&s1,const-MyStruct&s2)
{
if(s1.member1==s2.member1)
返回s1.member2>s2.member2;
其他的
返回s1.member1
我认为仅仅重载
操作符并不太难。首先,考虑“规范”。
订购关系:

struct Compare
{
    bool operator()( C const& lhs, C const& rhs ) const
    {
        return lhs.a < rhs.a
            || ( !(rhs.a < lhs.a) && lsh.b < rhs.b )
            || ( !(rhs.a < lhs.a) && !(rhs.b < lhs.b) && lhs.c < rhs .c )
            || ...
    }
};
剩下的就是以某种方式将其转化为某种东西 它可以处理任意元素的任意顺序 类型。有句老话说,解决每一个问题 是一个额外的间接层次,它适用于这里

首先,我们需要一些方法来处理不同类型的问题 每个元素。多态性似乎是合适的(尽管 如果模板的顺序 评估的元素在编译时固定):

最后,将这些实例的地址放入表中:

CompareOneElementOfC const* const cmp[] = { &c1, &c2 ... };
对于不同的订单,可以有不同的表。如果有 只有几个,为每个定义静态表,并使用 信息技术如果排序可以是任意的,请在 按所需顺序在每次分拣前飞行

最后:

class Compare
{
    CompareOneElementOfC const* const* begin;
    CompareOneElementOfC const* const* end;
public:
    template< size_t N >
    Compare( CompareOneElementOfC const* const (&cmp)[N] )
        : begin( cmp )
        , end( cmp + N )
    {
    }
    bool
    operator()( C const& lhs, C const& rhs ) const
    {
        auto current = begin;
        while ( current != end && (*current)->isEqual( lhs, rhs ) ) {
            ++ current;
        }
        return current != end && (*current)->isLessThan( lhs, rhs );
    }
}
类比较
{
比较元素常量*常量*开始;
比较元素常量*常量*结束;
公众:
模板
比较(CompareOneElementOfC常量*常量(&cmp)[N])
:开始(cmp)
,结束(cmp+N)
{
}
布尔
运算符()(C常量和左侧、C常量和右侧)常量
{
自动电流=开始;
while(current!=end&(*current)->isEqual(左侧、右侧)){
++电流;
}
返回电流!=结束和(*当前)->小于(左侧、右侧)的孤岛;
}
}
(请注意,我还没有实际测试这段代码,所以 可能是打字错误和其他错误。不过,基本的想法

“它几乎不支持c++11中的任何东西”-太糟糕了,一个具有元组魔力的lambda可以在这里创造奇迹。但是boost 1.39可能有元组(尤其是
tie
函数)。谢谢这是一个很好的解决方案,而且很有效。然而,它能确定某个地方(在模板中或作为参数)也有比较函数吗?例如,我在delphi CompareText中使用了for string,在其他类型中使用了std::greater等等。对不起,我试着自己想:)我认为这应该可以使用简单的重载函数,如果我是,请纠正我wrong@blizzard如果实现的表单只使用了少于的函数,则可以用简单函数替换函数对象,而不是功能对象;函数对象的优点是它支持两个独立的函数,一个用于排序,另一个用于相等。(另一个可能的优势是,它可以保存额外的数据,以某种方式控制比较。这通常不是很有用,但在某些情况下可能有用。)@blizzard当然,用额外的参数或数据成员扩展模板没有问题,或者(正如我提到的)针对具体案例使用手写比较。该模板更多的是作为一个示例,而不是一个独特的解决方案。谢谢,我已经这样做了(扩展排序方向等)。
class ComparisonClass {
public:
    bool operator()(const Struct& lhs, const Struct& rhs) {
        for(int i=0; i<m_comparisonOrder.size(); i++) {
            int pos = m_comparisonOrder[i];
            if (lhs[pos] != rhs[pos]) {
                if (m_comparisonType[pos])
                    return lhs[pos] < rhs[pos];
                else
                    return lhs[pos] > rhs[pos];
            }
        }
    }

    std::vector<int> m_comparisonOrder.
    std::vector<bool> m_comparisonType;
};
struct Compare
{
    bool operator()( C const& lhs, C const& rhs ) const
    {
        return lhs.a < rhs.a
            || ( !(rhs.a < lhs.a) && lsh.b < rhs.b )
            || ( !(rhs.a < lhs.a) && !(rhs.b < lhs.b) && lhs.c < rhs .c )
            || ...
    }
};
struct Compare
{
    bool operator()( C const& lhs, C const& rhs ) const
    {
        int i = 0;
        while ( i != N && !(lhs[i] < rhs[i]) && !(rhs[i] < lhs[i]) ) {
            ++ i;
        }
        return i != N && lhs[i] < rhs[i];
    }
};
struct Compare
{
    bool operator()( C const& lhs, C const& rhs ) const
    {
        int i = 0;
        while ( i != N && !(lhs[i] == rhs[i]) ) {
            ++ i;
        }
        return i != N && lhs[i] < rhs[i];
    }
};
struct CompareOneElementOfC
{
    virtual bool isLessThan( C const& lhs, C const& rhs) const = 0;
    virtual bool isEqual( C const& lhs, C const& rhs) const = 0;
};

template <typename T, T C::*ptr>
struct ConcreteCompareOneElementOfC : public CompareOneElementOfC
{
    virtual bool isLessThan( C const& lhs, C const& rhs) const
    {
        return lhs.*ptr < rhs.*ptr;
    }
    virtual bool isEqual( C const& lhs, C const& rhs) const
    {
        return lhs.*ptr == rhs.*ptr;
    }
};
ConcreteCompareOneElementOfC<int, &C::a> const c1;
ConcreteCompareOneElementOfC<double, &C::b> const c2;
//  ...
CompareOneElementOfC const* const cmp[] = { &c1, &c2 ... };
class Compare
{
    CompareOneElementOfC const* const* begin;
    CompareOneElementOfC const* const* end;
public:
    template< size_t N >
    Compare( CompareOneElementOfC const* const (&cmp)[N] )
        : begin( cmp )
        , end( cmp + N )
    {
    }
    bool
    operator()( C const& lhs, C const& rhs ) const
    {
        auto current = begin;
        while ( current != end && (*current)->isEqual( lhs, rhs ) ) {
            ++ current;
        }
        return current != end && (*current)->isLessThan( lhs, rhs );
    }
}