<algorithm> sort keeps generating error messages.
-
I am trying to get ``sort(begin, end, compare)`` to work, where begin and end are iterators and compare is a boolean function. The Asset constructor is commented out because it generates an error. I have tried to follow the example in Beginners guide to the std::sort() funct - C++ Articles[^] This is the code:
class RDA_Names {
struct Asset { //!< Aseet data
long long int asset_No = 0; //!< Converted Asset Tracking number
string asset_Name = ""; //!< Normalized Asset Name
//Asset(long long int asset, string name): asset_No(asset), asset_Name(name) {}
};struct {
bool compare(const Asset& lhs, const Asset& rhs) { return lhs.asset_No < rhs.asset_No; }
} comp;bool compare(const Asset& x, const Asset& y);
array asset_Data;
}; // class RDA_Names
bool RDA_Names::compare(const Asset& lhs, const Asset& rhs) {
return (lhs.asset_No < rhs.asset_No);
}; // bool RDA_Names::compare(const Asset& x, const Asset& y)void RDA_Names::post_process_names() {
sort(asset_Data.begin(), asset_Data.end()) // case 1
sort(asset_Data.begin(), asset_Data.end(), compare); // case 2
sort(asset_Data.begin(), asset_Data.end(), comp); // case 3
}; // void post_process_names()For each case, the other two cases are commented out. The format of the errors is Error number(repetition), Error text, lines within
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\
where the error was reported. Case 1:
C2893 (5) Failed to specialize function template
\include\algorithm Lines 7361, 7419, 7423, 7434, 7447
C2672 (5) 'operator __surrogate_func': no matching overloaded function found
\include\xutility Line 1622Case 2:
C2780 (1) 'void std::sort(const _RanIt,const _RanIt)': expects 2 arguments - 3 provided
C2672 (1) 'sort': no matching overloaded function found
C3867 (1) 'RDA_Names::compare': non-standard syntax; use '&' to create a pointer to memberCase 3:
C2064 (5) term does not evaluate to a function taking 2 arguments
\include\xutility Line 1622
\include\algorithm Lines 7419, 7423, 7434, 7447 -
I am trying to get ``sort(begin, end, compare)`` to work, where begin and end are iterators and compare is a boolean function. The Asset constructor is commented out because it generates an error. I have tried to follow the example in Beginners guide to the std::sort() funct - C++ Articles[^] This is the code:
class RDA_Names {
struct Asset { //!< Aseet data
long long int asset_No = 0; //!< Converted Asset Tracking number
string asset_Name = ""; //!< Normalized Asset Name
//Asset(long long int asset, string name): asset_No(asset), asset_Name(name) {}
};struct {
bool compare(const Asset& lhs, const Asset& rhs) { return lhs.asset_No < rhs.asset_No; }
} comp;bool compare(const Asset& x, const Asset& y);
array asset_Data;
}; // class RDA_Names
bool RDA_Names::compare(const Asset& lhs, const Asset& rhs) {
return (lhs.asset_No < rhs.asset_No);
}; // bool RDA_Names::compare(const Asset& x, const Asset& y)void RDA_Names::post_process_names() {
sort(asset_Data.begin(), asset_Data.end()) // case 1
sort(asset_Data.begin(), asset_Data.end(), compare); // case 2
sort(asset_Data.begin(), asset_Data.end(), comp); // case 3
}; // void post_process_names()For each case, the other two cases are commented out. The format of the errors is Error number(repetition), Error text, lines within
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\
where the error was reported. Case 1:
C2893 (5) Failed to specialize function template
\include\algorithm Lines 7361, 7419, 7423, 7434, 7447
C2672 (5) 'operator __surrogate_func': no matching overloaded function found
\include\xutility Line 1622Case 2:
C2780 (1) 'void std::sort(const _RanIt,const _RanIt)': expects 2 arguments - 3 provided
C2672 (1) 'sort': no matching overloaded function found
C3867 (1) 'RDA_Names::compare': non-standard syntax; use '&' to create a pointer to memberCase 3:
C2064 (5) term does not evaluate to a function taking 2 arguments
\include\xutility Line 1622
\include\algorithm Lines 7419, 7423, 7434, 7447 -
I am trying to get ``sort(begin, end, compare)`` to work, where begin and end are iterators and compare is a boolean function. The Asset constructor is commented out because it generates an error. I have tried to follow the example in Beginners guide to the std::sort() funct - C++ Articles[^] This is the code:
class RDA_Names {
struct Asset { //!< Aseet data
long long int asset_No = 0; //!< Converted Asset Tracking number
string asset_Name = ""; //!< Normalized Asset Name
//Asset(long long int asset, string name): asset_No(asset), asset_Name(name) {}
};struct {
bool compare(const Asset& lhs, const Asset& rhs) { return lhs.asset_No < rhs.asset_No; }
} comp;bool compare(const Asset& x, const Asset& y);
array asset_Data;
}; // class RDA_Names
bool RDA_Names::compare(const Asset& lhs, const Asset& rhs) {
return (lhs.asset_No < rhs.asset_No);
}; // bool RDA_Names::compare(const Asset& x, const Asset& y)void RDA_Names::post_process_names() {
sort(asset_Data.begin(), asset_Data.end()) // case 1
sort(asset_Data.begin(), asset_Data.end(), compare); // case 2
sort(asset_Data.begin(), asset_Data.end(), comp); // case 3
}; // void post_process_names()For each case, the other two cases are commented out. The format of the errors is Error number(repetition), Error text, lines within
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\
where the error was reported. Case 1:
C2893 (5) Failed to specialize function template
\include\algorithm Lines 7361, 7419, 7423, 7434, 7447
C2672 (5) 'operator __surrogate_func': no matching overloaded function found
\include\xutility Line 1622Case 2:
C2780 (1) 'void std::sort(const _RanIt,const _RanIt)': expects 2 arguments - 3 provided
C2672 (1) 'sort': no matching overloaded function found
C3867 (1) 'RDA_Names::compare': non-standard syntax; use '&' to create a pointer to memberCase 3:
C2064 (5) term does not evaluate to a function taking 2 arguments
\include\xutility Line 1622
\include\algorithm Lines 7419, 7423, 7434, 7447Case 1 fails because there's no comparison function for
sort
. It might work ifAsset
definedoperator<
, but I'd have to check. EDIT: If you definebool Asset::operator<(const Asset& that)
, then case 1 also compiles. Case 2 fails becausecompare
takes athis
pointer. If a comparison function is going to be part of a class, it needs to be declaredstatic
. Case 3, I'd have to investigate. I've used thisstruct
technique, but only for aset
I believe. It's likely thatarray
doesn't use it. Try making yourcompare
function a free function (outside the class) orstatic
and see what happens in case 2. In the meantime, I'll look at this further. * * * Fixing case 2 looks like the way to go. I compiled the following successfully, and the constructor didn't give me any problems:class RDA_Names {
struct Asset {
long long int asset_No = 0;
string asset_Name = "";
Asset(long long int asset, string name): asset_No(asset), asset_Name(name) {}
};// struct {
// bool compare(const Asset& lhs, const Asset& rhs) { return lhs.asset_No < rhs.asset_No; }
// } comp;static bool compare(const Asset& x, const Asset& y);
void post_process_names();
array asset_Data;
}; // class RDA_Names
bool RDA_Names::compare(const Asset& lhs, const Asset& rhs) {
return (lhs.asset_No < rhs.asset_No);
}; // bool RDA_Names::compare(const Asset& x, const Asset& y)void RDA_Names::post_process_names() {
// sort(asset_Data.begin(), asset_Data.end()); // case 1
std::sort(asset_Data.begin(), asset_Data.end(), compare); // case 2
// sort(asset_Data.begin(), asset_Data.end(), comp); // case 3
}; // void post_process_names()Robust Services Core | Software Techniques for Lemmings | Articles
The fox knows many things, but the hedgehog knows one big thing. -
I am trying to get ``sort(begin, end, compare)`` to work, where begin and end are iterators and compare is a boolean function. The Asset constructor is commented out because it generates an error. I have tried to follow the example in Beginners guide to the std::sort() funct - C++ Articles[^] This is the code:
class RDA_Names {
struct Asset { //!< Aseet data
long long int asset_No = 0; //!< Converted Asset Tracking number
string asset_Name = ""; //!< Normalized Asset Name
//Asset(long long int asset, string name): asset_No(asset), asset_Name(name) {}
};struct {
bool compare(const Asset& lhs, const Asset& rhs) { return lhs.asset_No < rhs.asset_No; }
} comp;bool compare(const Asset& x, const Asset& y);
array asset_Data;
}; // class RDA_Names
bool RDA_Names::compare(const Asset& lhs, const Asset& rhs) {
return (lhs.asset_No < rhs.asset_No);
}; // bool RDA_Names::compare(const Asset& x, const Asset& y)void RDA_Names::post_process_names() {
sort(asset_Data.begin(), asset_Data.end()) // case 1
sort(asset_Data.begin(), asset_Data.end(), compare); // case 2
sort(asset_Data.begin(), asset_Data.end(), comp); // case 3
}; // void post_process_names()For each case, the other two cases are commented out. The format of the errors is Error number(repetition), Error text, lines within
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\
where the error was reported. Case 1:
C2893 (5) Failed to specialize function template
\include\algorithm Lines 7361, 7419, 7423, 7434, 7447
C2672 (5) 'operator __surrogate_func': no matching overloaded function found
\include\xutility Line 1622Case 2:
C2780 (1) 'void std::sort(const _RanIt,const _RanIt)': expects 2 arguments - 3 provided
C2672 (1) 'sort': no matching overloaded function found
C3867 (1) 'RDA_Names::compare': non-standard syntax; use '&' to create a pointer to memberCase 3:
C2064 (5) term does not evaluate to a function taking 2 arguments
\include\xutility Line 1622
\include\algorithm Lines 7419, 7423, 7434, 7447To complement what Greg was saying: - case 3 fails because
comp
is a structure not a function returning a bool. Try changing it to:bool comp (const RDA_Names::Asset& lhs, const RDA_Names::Asset& rhs)
{
return lhs.asset_No < rhs.asset_No;
}You will have to also make
Asset
structure public. As a case 4 you can try this:sort (asset_Data.begin (), asset_Data.end (), [](auto& l, auto& r)->bool {
return l.asset_No < r.asset_No; });where the comparison function is an anonymous lambda. The next step is to look at how efficient your code will be. If you are sorting only 500 objects and you don't do it too often, it's probably OK. In general however your solution is highly inefficient. Every time
sort
has to exchange two elements it makes copies of theasset_Name
string. There are various ways to improve it: - keep aunique_ptr
pointer to string and provide a move constructor for theAsset
structure. - create an array of indexes inRDA_Names
and sort it inseted of sorting theasset_Data
array.Mircea
-
Case 1 fails because there's no comparison function for
sort
. It might work ifAsset
definedoperator<
, but I'd have to check. EDIT: If you definebool Asset::operator<(const Asset& that)
, then case 1 also compiles. Case 2 fails becausecompare
takes athis
pointer. If a comparison function is going to be part of a class, it needs to be declaredstatic
. Case 3, I'd have to investigate. I've used thisstruct
technique, but only for aset
I believe. It's likely thatarray
doesn't use it. Try making yourcompare
function a free function (outside the class) orstatic
and see what happens in case 2. In the meantime, I'll look at this further. * * * Fixing case 2 looks like the way to go. I compiled the following successfully, and the constructor didn't give me any problems:class RDA_Names {
struct Asset {
long long int asset_No = 0;
string asset_Name = "";
Asset(long long int asset, string name): asset_No(asset), asset_Name(name) {}
};// struct {
// bool compare(const Asset& lhs, const Asset& rhs) { return lhs.asset_No < rhs.asset_No; }
// } comp;static bool compare(const Asset& x, const Asset& y);
void post_process_names();
array asset_Data;
}; // class RDA_Names
bool RDA_Names::compare(const Asset& lhs, const Asset& rhs) {
return (lhs.asset_No < rhs.asset_No);
}; // bool RDA_Names::compare(const Asset& x, const Asset& y)void RDA_Names::post_process_names() {
// sort(asset_Data.begin(), asset_Data.end()); // case 1
std::sort(asset_Data.begin(), asset_Data.end(), compare); // case 2
// sort(asset_Data.begin(), asset_Data.end(), comp); // case 3
}; // void post_process_names()Robust Services Core | Software Techniques for Lemmings | Articles
The fox knows many things, but the hedgehog knows one big thing.Although it's a waste of time to say this, And I know you've heard it before. But your answers were most pointed And it clearly went to the fore. We thank you all My wife because I don't grumble I with nothing to grumble about. I have tried to follow all of your suggestions (my following is full). I now have pointers or references everywhere and the thing seems to compile without complaint. Now to get rid of those damn'd nuisance run-time errors. thanks!
-
To complement what Greg was saying: - case 3 fails because
comp
is a structure not a function returning a bool. Try changing it to:bool comp (const RDA_Names::Asset& lhs, const RDA_Names::Asset& rhs)
{
return lhs.asset_No < rhs.asset_No;
}You will have to also make
Asset
structure public. As a case 4 you can try this:sort (asset_Data.begin (), asset_Data.end (), [](auto& l, auto& r)->bool {
return l.asset_No < r.asset_No; });where the comparison function is an anonymous lambda. The next step is to look at how efficient your code will be. If you are sorting only 500 objects and you don't do it too often, it's probably OK. In general however your solution is highly inefficient. Every time
sort
has to exchange two elements it makes copies of theasset_Name
string. There are various ways to improve it: - keep aunique_ptr
pointer to string and provide a move constructor for theAsset
structure. - create an array of indexes inRDA_Names
and sort it inseted of sorting theasset_Data
array.Mircea
Your first point is right on, and gets me back to Case 2. You're second point is incorrect. What is being sorted is an object of some type. The sort routine ignores the type and whether the object containing the type is private or public. It only works on comparison, I assume signed char comparison if there is no comparison function, and the ability to index and swap. The comparison function has no cognizance of privacy, it is only passed pointers/objects and returns a bool. At the sort base level, the input object need not be public, and if the input object contains objects, these contained objects need not be public. Just guessing. thanks
-
Your first point is right on, and gets me back to Case 2. You're second point is incorrect. What is being sorted is an object of some type. The sort routine ignores the type and whether the object containing the type is private or public. It only works on comparison, I assume signed char comparison if there is no comparison function, and the ability to index and swap. The comparison function has no cognizance of privacy, it is only passed pointers/objects and returns a bool. At the sort base level, the input object need not be public, and if the input object contains objects, these contained objects need not be public. Just guessing. thanks
Quote:
Just guessing.
Well, you didn't guess right :) Pretty much all you said is valid for the old C
qsort
function.std::sort
is an entirely different beast. I suggest you carefully read the description at std::sort - cppreference.com[^]Quote:
The sort routine ignores the type and whether the object containing the type is private or public.
I'm not sure I understand what you mean by "the object containing the type". In C++ objects don't contain types. Besides the sort routine is not ignoring the object type at all. According to C++ reference: "The type of dereferenced RandomIt must meet the requirements of MoveAssignable and MoveConstructible". That requires at least a copy constructor for the object (either user defined or generated by the compiler).
Quote:
The comparison function has no cognizance of privacy, it is only passed pointers/objects and returns a bool.
Of course not, the comparison function needs to access the members of the object in order to compare them. Either it is a member function or a friend function or the members in question are public. The example on the C++ reference page mentioned above shows all the different methods you can use to invoke the std::sort algorithm.
Mircea