C++ std::sort() - 无法对访问成员变量的 class 类型的向量进行排序
C++ std::sort() - Unable to sort a vector of a class type that access member variables
Entry.h
:
//returns the sum of all non mega entry percentages
float sumOfNonMegaEntryPct(vector<Number>& arg1_Numbers);
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
:
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
:
#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
:
vector<Entry> copyGameEntry = game.getPlayEntry();
sort(copyGameEntry.begin(), copyGameEntry.end(),
bind(&Lotto::compareEntry_sumPct_nonMega, game));
这只是代码的一部分,但我认为这足以说明问题。编译时出现错误:
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
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
问题:
可能是什么问题?
您的错误 与:bind(&Lotto::compareEntry_sumPct_nonMega, game)
有关。
您需要指定std::placeholders when you call function std::bind,它将按指定的顺序被调用、返回的函数对象的参数替换。
您可以使用以下 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";
}
在您的情况下,您需要添加:
using namespace std::placeholders;
auto func_obj = bind(&Lotto::compareEntry_sumPct_nonMega, game, _1, _2);
然后,func_obj (_1, _2)
将由 sort()
在内部调用,如:
func_obj(copyGameEntry[i], copyGameEntry[i+1]);
或者,您可以尝试使用类似的东西:
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));
有其他方法可以调用 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));
}
很可能,在你的情况下你缺少 std::placeholders
您使用的 std::bind
不正确。您需要为未绑定的参数使用占位符:
using namespace std::placeholders;
sort(copyGameEntry.begin(), copyGameEntry.end(),
bind(&Lotto::compareEntry_sumPct_nonMega, game, _1, _2));
N.B。此绑定表达式将复制 game
对象,因此您应该使用 std::ref(game)
或仅使用 &game
来避免不必要的复制。
或者使用 lambda 函数:
sort(copyGameEntry.begin(), copyGameEntry.end(),
[&game](Entry& l, Entry& r) {
return game.compareEntry_sumPct_nonMega(l, r);
});
Entry.h
:
//returns the sum of all non mega entry percentages
float sumOfNonMegaEntryPct(vector<Number>& arg1_Numbers);
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
:
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
:
#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
:
vector<Entry> copyGameEntry = game.getPlayEntry();
sort(copyGameEntry.begin(), copyGameEntry.end(),
bind(&Lotto::compareEntry_sumPct_nonMega, game));
这只是代码的一部分,但我认为这足以说明问题。编译时出现错误:
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
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
问题:
可能是什么问题?
您的错误 与:bind(&Lotto::compareEntry_sumPct_nonMega, game)
有关。
您需要指定std::placeholders when you call function std::bind,它将按指定的顺序被调用、返回的函数对象的参数替换。
您可以使用以下 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";
}
在您的情况下,您需要添加:
using namespace std::placeholders;
auto func_obj = bind(&Lotto::compareEntry_sumPct_nonMega, game, _1, _2);
然后,func_obj (_1, _2)
将由 sort()
在内部调用,如:
func_obj(copyGameEntry[i], copyGameEntry[i+1]);
或者,您可以尝试使用类似的东西:
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));
有其他方法可以调用 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));
}
很可能,在你的情况下你缺少 std::placeholders
您使用的 std::bind
不正确。您需要为未绑定的参数使用占位符:
using namespace std::placeholders;
sort(copyGameEntry.begin(), copyGameEntry.end(),
bind(&Lotto::compareEntry_sumPct_nonMega, game, _1, _2));
N.B。此绑定表达式将复制 game
对象,因此您应该使用 std::ref(game)
或仅使用 &game
来避免不必要的复制。
或者使用 lambda 函数:
sort(copyGameEntry.begin(), copyGameEntry.end(),
[&game](Entry& l, Entry& r) {
return game.compareEntry_sumPct_nonMega(l, r);
});