简体   繁体   English

C ++ std :: sort()-无法对访问成员变量的类类型的向量进行排序

[英]C++ std::sort() - Unable to sort a vector of a class type that access member variables

Entry.h : Entry.h

//returns the sum of all non mega entry percentages
float sumOfNonMegaEntryPct(vector<Number>& arg1_Numbers);

Entry.cpp : Entry.cpp

//returns the sum of all mega entry percentages
float Entry::sumOfMegaEntryPct(vector<MegaNumber>& arg1_MegaNumbers)
{
    float sumPct = 0.00f;
     for (MegaNumber c : megaEntry)
     {
         sumPct = sumPct + arg1_MegaNumbers[c.getID()].getOccurencePct();
     }

     return sumPct;
}

Lotto.h : Lotto.h

public:
//compares two entries, used for sorting algorithm, sorts by nonmega number
bool compareEntry_sumPct_nonMega(Entry arg1, Entry arg2); 

    protected:
    vector<Numbers> numbers;
    vector<MegaNumbers> megaNumbers;

Lotto.cpp : Lotto.cpp

#include "lotto.h"

//sorts nonmega numbers by sum of their pct, used for sort algorithm
bool Lotto::compareEntry_sumPct_nonMega(Entry arg1, Entry arg2)
{
    bool b = arg1.sumOfNonMegaEntryPct(numbers) < arg2.sumOfNonMegaEntryPct(numbers);
     return b;
}

Source.cpp : Source.cpp

vector<Entry> copyGameEntry = game.getPlayEntry();
sort(copyGameEntry.begin(), copyGameEntry.end(),
     bind(&Lotto::compareEntry_sumPct_nonMega, game));

This is just a part of the code, but I think it's enough to make sense. 这只是代码的一部分,但我认为足够了。 When compiling, I get the error(s): 编译时,出现错误:

Severity Code Description Project File Line Error C2451 conditional expression of type 'std::_Unforced' is illegal Lottery Sort e:\\program files (x86)\\microsoft visual studio 14.0\\vc\\include\\algorithm 3133 严重性代码说明项目文件行错误C2451类型为'std :: _ Unforced'的条件表达式无效抽奖排序e:\\ program files(x86)\\ microsoft visual studio 14.0 \\ vc \\ include \\ algorithm 3133

Severity Code Description Project File Line Error C2675 unary '!': 'std::_Unforced' does not define this operator or a conversion to a type acceptable to the predefined operator Lottery Sort e:\\program files (x86)\\microsoft visual studio 14.0\\vc\\include\\algorithm 3118 严重性代码说明项目文件行错误C2675一元'!':'std :: _ Unforced'未定义此运算符或对预定义运算符可接受的类型的转换彩票排序e:\\ program files(x86)\\ microsoft visual studio 14.0 \\ vc \\ include \\ algorithm 3118

Question: 题:

What could be the problem ? 可能是什么问题呢 ?

You are using std::bind incorrectly. 您使用的std::bind错误。 You need to use placeholders for the unbound arguments: 您需要为未绑定的参数使用占位符:

using namespace std::placeholders;
sort(copyGameEntry.begin(), copyGameEntry.end(),
     bind(&Lotto::compareEntry_sumPct_nonMega, game, _1, _2));

NB this bind expression will copy the game object, so you should either use std::ref(game) or just &game instead, to avoid an unnecessary copy. 注意,此绑定表达式将复制game对象,因此应使用std::ref(game)或仅使用&game来避免不必要的复制。

Or use a lambda function: 或使用lambda函数:

sort(copyGameEntry.begin(), copyGameEntry.end(),
     [&game](Entry& l, Entry& r) {
       return game.compareEntry_sumPct_nonMega(l, r);
     });

There are alternatives to invoke std::sort: 有一些替代方法可以调用std :: sort:

#include <algorithm>
#include <vector>

struct X
{
    int value;
    bool operator < (const X& other) const { return value < other.value; }
    static bool less(const X& a, const X& b) { return a.value < b.value; }
};

struct Holder
{
    bool less(const X& a, const X& b) const { return a.value < b.value; }
};

int main ()
{
    Holder holder;
    std::vector<X> values;

    // No stateful comparison
    std::sort(values.begin(), values.end());

    // No stateful comparison
    std::sort(values.begin(), values.end(), X::less);

    // Stateful comparison
    struct Less {
        const Holder& holder;
        Less(const Holder& holder) : holder(holder) {}
        bool operator ()(const X& a, const X& b) const { return holder.less(a, b); }
    };
    std::sort(values.begin(), values.end(), Less(holder));

    // Stateful comparison
    std::sort(values.begin(), values.end(), [&holder](const X& a, const X& b) {
        return holder.less(a, b);
    });

    // Stateful comparison
    using namespace std::placeholders;
    std::sort(values.begin(), values.end(), std::bind(&Holder::less, holder, _1, _2));
}

Likely, in your case you are missing std::placeholders 在您的情况下,可能会缺少std :: placeholders

Your error is related to: bind(&Lotto::compareEntry_sumPct_nonMega, game) . 您的错误与以下内容有关: bind(&Lotto::compareEntry_sumPct_nonMega, game)

You need to specify std::placeholders when you call function std::bind , which will be replaced by the arguments of the called, returned function object, in the specified order. 调用函数std :: bind时 ,需要指定std :: placeholders ,它将按指定顺序被调用的返回函数对象的参数替换。

You could verify using the following try - catch block: 您可以使用以下try - catch块进行验证:

try {
    std::sort(copyGameEntry.begin(), copyGameEntry.end(),
              bind(&Lotto::compareEntry_sumPct_nonMega, game)

} catch (std::bad_function_call& e) {
    std::cout << "ERROR: Bad function call\n";

}

In your case you need to add: 在您的情况下,您需要添加:

using namespace std::placeholders;
auto func_obj = bind(&Lotto::compareEntry_sumPct_nonMega, game, _1, _2);

then, the func_obj (_1, _2) will be called, internally by sort() , as: 然后, func_obj (_1, _2)将在内部由sort()调用为:

func_obj(copyGameEntry[i], copyGameEntry[i+1]);

Alternatively , you can try using something like: 或者 ,您可以尝试使用以下方法:

struct Holder{
    bool less(const Entry& a, const Entry& b) const { 
        return a.sumOfNonMegaEntryPct(numbers) < b.sumOfNonMegaEntryPct(numbers); 
    }
} holder;

struct Less {
    const Holder& holder;
    Less(const Holder& holder) : holder(holder) {}
    bool operator ()(const Entry& a, const Entry& b) const { return holder.less(a, b); }
};

std::sort(copyGameEntry.begin(), copyGameEntry.end(), Less(holder));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM