Template function overloading. Understanding char - c++

I have a simple code that compares couple values. I'm using template function to reduce the amount of code, so i overloaded function twice(for different cases).
//cmp.h
template <class T>
bool cmp(T x,T y)
{
if(x == y)
{
return true;
}else
return false;
}
template <class T>
bool cmp(T *x,T *y)
{
if(*x==*y)
{ return true;}else
return false;
}
//main.cpp
#include <iostream>
#include <string>
#include "cmp.h"
using std::cout;
using std::endl;
using std::string;
int main() {
int aInt = 1, bInt = 2;
double aDouble = 3.0, bDouble = 3.0;
char aChars[5] = "haha", bChars[5] = "hahb";
char taChars[6] = "trick", tbChars[6] = "trick";
string aStr = "haha", bStr = "aha";
int* aIntPtr = &aInt, *bIntPtr = &bInt;
cout << cmp(aInt, bInt)<< endl;
cout << cmp(aDouble, bDouble)<< endl;
cout << cmp(aChars, bChars)<< endl;//i can't figure out why char prints out true here ???
cout << cmp(taChars, tbChars)<< endl;
cout << cmp(aStr, bStr)<< endl;
cout << cmp(aIntPtr, bIntPtr)<< endl;
cout << cmp(&aDouble, &bDouble) << endl;
return 0;
}
My output is:
0
1
1
1
0
0
1
And i expected:
0
1
0
1
0
0
1
Why it shows that two strings are identical ? Why if i entirely change the word, lets say
char aChars[5] = "jack", bChars[5] = "hahb";
then only it gives the right result. Isn't my second overloaded function should handle this right? (bool cmp(T *x,T *y))

Why it shows that two strings are identical ?
Because
template <class T>
bool cmp(T *x,T *y)
{
if(*x == *y)
{
return true;
}else
return false;
}
check only the first value pointed by x and y.
So when you check
char aChars[5] = "haha", bChars[5] = "hahb";
cout << cmp(aChars, bChars)<< endl;//
check that h is equal to h.
If you want check the equality between strings (and if you want avoid the use of the good-old std::strcmp()) you have to check all characters until the first zero.
But this is true for old style C-string; I don't think it's a good idea to develop a function that check equality between pointer for a generic type T.
-- EDIT --
Could u guide me please
To give an example... it's a lot of time that I don't think in plain C but something as follows should works
bool cmp (char const * p1, char const * p2)
{
for ( ; *p1 && *p1 == *p2 ; ++p1, ++p2 )
;
return *p1 == *p2;
}
Off Topic: you write code as
bool cmp(T *x,T *y)
{
if(*x==*y)
{ return true;}else
return false;
}
It's equivalent to
bool cmp(T *x,T *y)
{ return *x == *y; }
More generally speaking... if you have a code of type
if ( someTest )
return true;
else
return false;
and the function return a bool (or someTest is of type bool), you can write (and, IMHO, is more readable and elegant) simply write
return someTest;

Why it shows that two strings are identical ?
Array decays to pointer, so char taChars[6] will use overload template <class T>
bool cmp(T *x,T *y) and so compare only first element (which are equal in your case).
In C++17, you might do:
template <typename T>
bool cmp(const T& lhs, const T& rhs)
{
if constexpr (std::is_pointer<T>::value) {
return *lhs == *rhs;
} else if constexpr (std::is_array<T>::value) {
return std::equal(std::begin(lhs), std::end(lhs), std::begin(rhs), std::end(rhs));
} else {
return lhs == rhs;
}
}
Demo

Related

Variable values are changing

I have a template class that I am testing:
class SparseMat {
private:
FHvector<FHlist<MatNode<Object>>> matrix;
int numOfRows, numOfCols;
const Object defaultValue;
public:
SparseMat(int r, int c, const Object& defaultVal);
const Object & get(int r, int c) const;
bool set(int r, int c, const Object& x);
};
template <class Object>
SparseMat<Object>::SparseMat(int r, int c, const Object& defaultVal) : defaultValue(defaultVal) {
numOfRows = r;
numOfCols = c;
matrix.resize(numOfRows);
for (int counter = 0; counter < numOfRows; counter++) {
FHlist<MatNode<Object>> currentRow;
matrix.push_back(currentRow);
}
}
template <class Object>
bool SparseMat<Object>::set(int r, int c, const Object& x) {
if (r >= numOfRows || r < 0 || c < 0 || c >= numOfCols) {
return false;
}
if (r == 9 && c == 9) {
cout << x << endl;
}
if (r == 9 && c == 9) {
cout << x << endl;
}
for (FHlist<MatNode<Object>>::iterator iter = matrix[r].begin(); iter != matrix[r].end(); ++iter) {
if ((*iter).getCol() == c) {
if (x == defaultValue) {
matrix[r].erase(iter);
return true;
}
else {
(*iter).data = x;
return true;
}
}
}
matrix[r].push_back(MatNode<Object>(c, x));
return true;
}
template <class Object>
const Object & SparseMat<Object>::get(int r, int c) const {
if (r >= numOfRows || r < 0 || c < 0 || c >= numOfCols) {
throw OutOfBoundsException();
}
FHlist<MatNode<Object>> wantedRow = matrix[r];
for (FHlist<MatNode<Object>>::iterator iter = wantedRow.begin(); iter != wantedRow.end(); ++iter) {
if ((*iter).getCol() == c) {
return (*iter).getData();
}
}
return NULL;
}
MatNode is as follows:
template <class Object>
class MatNode
{
protected:
int col;
public:
Object data;
MatNode(int cl = 0, Object dt = Object()) : col(cl), data(dt) { }
int getCol() const { return col; }
const Object & getData() const {return data; }
};
The immensely strange thing is my two outputs print two different things. The first prints 21, as expected. The second prints out some random float, which is definitely not expected as I have changed nothing with x between the two outputs.
#include <iostream>
using namespace std;
#include "FHsparseMat.h"
#define MAT_SIZE 100000
typedef SparseMat<float> SpMat;
int main()
{
SpMat mat(MAT_SIZE, MAT_SIZE, 0);
mat.set(3, 9, 21);
cout << mat.get(3, 9) << endl;
mat.set(9, 9, 21);
cout << mat.get(9, 9) << endl;
mat.set(9, 9, mat.get(3,9));
cout << mat.get(9, 9) << endl;
}
Here is my tester. If I replace mat.get(3,9) with the hard coded value of 21, the issue disappears, if that helps.
get() has a return type of const Object &.
As a result, the final line of the function
return 0; // source code says NULL but preprocessor replaces that with 0
is returning a dangling reference to a temporary Object implicitly constructed with the value 0.
Using that dangling reference will, of course, cause undefined behavior.
It's not completely clear why that line is reached, but the logic that erases an item if you write the same value to the same location certainly seems suspicious. IMO you should only remove an item when the value written is zero.
The issue is that Object MatNode::getData() const is not returning a reference, and you are returning a reference in const Object & SparseMat<Object>::get(int r, int c) const. Change it to:
Object SparseMat<Object>::get(int r, int c) const.

C++ add value into stack subscript requires array or pointer type and warning

I'm new to programming in C++. Also new to implementing stacks. My objective is creating RPN Calculator using template stack. Cant use the built in stack classes.
I have everything so far and now I am stuck, I can't think of how to fix this problem. I am currently getting these errors:
Error C2109 subscript requires array or pointer type
Warning C4244 'return': conversion from 'double' to 'int', possible loss of data
This is my stack class:
#include<stack>
#define STACK_MAX 500
template<class T>
class RPNCalculator
{
private:
//Insanciating stack class
T data[STACK_MAX];
int size;
//stack<T> rpnstack;
public:
RPNCalculator() {
size = 0;
}
~RPNCalculator();
int Top() {
if (size == 0) {
fprintf(stderr, "Error: stack empty\n");
return -1;
}
return data[size - 1];
}
void push(T data); // pushes a new operand onto the stack
// the following operations are to be performed as defined for Reverse Polish Notation
// binary operators:
T value(); // returns the topmost value
void pop(); // returns the topmost value and pops it off the top
double add();
double subtract();
double multiply();
double divide();
// unary operators:
double square(); // squares the current value
double negate(); // negates, i.e. 3 becomes -3
bool isEmpty(); // tests to see if there are elements on the stack
void clear(); // clears out the stack
};
template<class T>
inline bool RPNCalculator<T>::isEmpty()
{
bool status;
if (!top)
status = true;
else
status = false;
return status;
}
template<class T>
void RPNCalculator<T>::clear()
{
}
template<class T>
inline RPNCalculator<T>::~RPNCalculator()
{
}
template<class T>
inline void RPNCalculator<T>::push(T data)
{
if (size < STACK_MAX)
data[size++] = data;
else
fprintf(stderr, "Error: stack full\n");
}
template<class T>
inline T RPNCalculator<T>::value()
{
return T();
}
template<class T>
inline void RPNCalculator<T>::pop()
{
if (size == 0)
fprintf(stderr, "Error: stack empty\n");
else
size--;
}
This is my main class:
#include <iostream>
#include "RPNCalculator.h"
#include <string>
#include <sstream>
using namespace std;
bool isOperator(const string& input);
void performOperation(const string& st, RPNCalculator<double>& rpnstack);
int main() {
cout << "Welcome to the RPN Calculator by AbdulFatai Saliu __D00168401" << endl;
cout << "Enter c to clear \n"
<< "s to square \n"
<< "n to negate \n"
<< "p to pop current value \n"
<< "q to quit \n"
;
RPNCalculator<double> rnpstack;
string input;
while (true) {
//Dispaly prompt
cout << ">> ";
//get user input
cin >> input;
//check for numeric values
double numereric;
if (istringstream(input) >> numereric) {
}
else if (isOperator(input)) {
}
else if (input == "q") {
return 0;
}
else {
cout << "Input Not Valid" << endl;
}
//check for operators
//check for exit
// display invalid value message
}
system("PAUSE");
//return 0;
}
bool isOperator(const string& input) {
string operators[] = { "-","+","*","/"};
for (int i = 0; i < 6; i++) {
if (input == operators[i]) {
return true;
}
}
return false;
}
void performOperation(const string& input, RPNCalculator<double>& rpnstack) {
double firstValue, secondValue, result;
firstValue = rpnstack.Top();
rpnstack.pop();
secondValue = rpnstack.Top();
rpnstack.pop();
if (input == "-") {
result = secondValue - firstValue;
}
else if (input == "+") {
result = secondValue + firstValue;
}
else if (input == "*") {
result = secondValue * firstValue;
}
else if (input == "/") {
result = secondValue / firstValue;
}
cout << result << endl;
rpnstack.push(result);
}
the problem seems to be coming from my push() method in the RPNCalculator template class.
Looks like you have a parameter for the function void push(T data); where the parameter has the same name as the class member (data, your storage). Try changing the parameter name in the function implementation that doesn't yield this conflict. You could also be specific which data you want to use if you really want to use that name.
Try this one instead
template<class T>
inline void RPNCalculator<T>::push(T arg)
{
if (size < STACK_MAX)
data[size++] = arg;
else
fprintf(stderr, "Error: stack full\n");
}
or, if you want to be explicit about which data you are assigning
template<class T>
inline void RPNCalculator<T>::push(T data)
{
if (size < STACK_MAX)
this->data[size++] = data; // this->data is the member, data is the function local variable
else
fprintf(stderr, "Error: stack full\n");
}
This is usually avoided by naming the member variables in a way where there can't be conflicts. One way is to prefix your members with m_, where data would become m_data. Feel free to use any style of code that you want, but I'd suggest avoiding conflicts (and the second approach) when possible.

Problem declaring class objects outside of conditional statement because of template function

For my c++ class we were given the task of writing a template class who's class object's type is defined by the user using templates.
Code snipit from main:
if (dataType == "1" || dataType == "int") {
simpleVector<int> userArray;
} else if (dataType == "2" || dataType == "double") {
simpleVector<double> userArray;
} else if (dataType == "3" || dataType == "char") {
simpleVector<char> userArray;
} else if {
simpleVector<string> userArray;
}
userArray.setDefaultArray();
From this I get error code C2065 - undeclared identifier error. I see why I am getting the error but i do not know how I can declare userArray before I know the data type.
Source Code:
#include <stdio.h>
#include <string>
using std::string;
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
template<class T>
class simpleVector {
public:
void setDefaultArray ();
void setArraySize (int size);
void copy (T *arr);
void desctruct ();
int getArraySize ();
T getElementAt (int index);
void fillArray();
private:
int arraySize;
T *myArray;
};
int main () {
string dataType;
int arraySize;
bool loopCondition = false;
do {
cout << "Data Type:";
cin >> dataType;
if (dataType == "1" || dataType == "2" || dataType == "3" || dataType == "4"
|| dataType == "int" || dataType == "double" || dataType == "char" || dataType == "string") {
loopCondition = false;
} else {
cout << "WARNING: invalid data type entered." << endl;
cout << "Valid entries are (1.int, 2.double, 3.char, 4.string)" << endl;
loopCondition = true;
}
} while (loopCondition);
if (true)
int num = 9;
else
int num = 7;
int num2 = num;
//simpleVector userArray; //?? Review
if (dataType == "1" || dataType == "int") {
simpleVector<int> userArray;
} else if (dataType == "2" || dataType == "double") {
simpleVector<double> userArray;
} else if (dataType == "3" || dataType == "char") {
simpleVector<char> userArray;
} else if (dataType == "4" || dataType == "char") {
simpleVector<string> userArray;
}
userArray.setDefaultArray();
cout << "Number of Inputs:";
cin >> arraySize;
userArray.setArraySize(arraySize);
userArray.fillArray();
return 0;
}
//Should call desctruct before this if reusing.
template<class T>
void simpleVector<T>::setDefaultArray() {
arraySize = 0;
myArray = NULL; //note: NULL is case sensitive (#include <stdio.h>)
}
template<class T>
void simpleVector<T>::setArraySize (int size) {
myArray = new T[size];
}
template<class T>
void simpleVector<T>::copy (T *arr) {
//ToDo
}
template<class T>
void simpleVector<T>::desctruct () {
//ToDo
}
template<class T>
int simpleVector<T>::getArraySize () {
//ToDo
}
template<class T>
T simpleVector<T>::getElementAt (int index) {
//ToDo
}
template<class T>
void simpleVector<T>::fillArray() {
cout << "Enter Array Values" << endl;
for (int i; i < arraySize; i++) {
cout << "Element " + i + ":";
cin >> myArray[i];
}
}
Thanks,
Mike
The code in Eugene's answer looks great, but is maybe too complicated for learning C++?
A very simple solution could look like this
declare a class vectorBase, which declares all the methods you need in all your vectors
let the templated class inherit from vectorBase
template
class simpleVector : public vectorBase { ...
then declare a pointer of type vectorBase before your
if (dataType == "1" || dataType == "int") ...
in the if-block assign the newly created userArrays to the base class pointer
later, access the methods through the baseClass pointer, which is identical for all specific template classes
You can't do this, because types determination are a compile-time process. Use inheritance instead templates, if you want to determine types at runtime.
Also I can suggest you the "variant" pattern. For example:
#include <memory>
#include <string>
class variant
{
public:
template <class T>
variant& operator = (T const& t)
{
typedef type<T> assign_type;
object = std::auto_ptr<assign_type>(new assign_type(t));
return *this;
}
template <class T>
operator T ()
{
typedef type<T> assign_type;
assign_type& type = dynamic_cast<assign_type&>(*object);
return type.get();
}
private:
class base
{
public:
virtual ~base() {}
};
typedef std::auto_ptr<base> base_ptr;
template <class T>
class type : public base
{
public:
type(T const& t)
: object(t)
{
}
T get() const
{
return object;
}
private:
T object;
};
base_ptr object;
};
struct dummy
{
int a;
int b;
int c;
};
int main()
{
variant v1, v2, v3, v4;
v1 = 2;
v2 = 5.0f;
v3 = std::string("Pot of gold");
v4 = dummy();
int i = v1;
float f = v2;
std::string s = v3;
dummy d = v4;
return 0;
}
As I understand, the intention of this problem is to teach how template usage is limited by type definition on compile time. It's pretty straightforward that user's choice will be limited by some list of types which developer cared to explicitly specify. Now the question is - how it affects the resulting program?
First, you should realize that code-paths for all possible values of your template argument will be instantiated on compile time. In other words, binary code for setDefaultArray, setArraySize, fillArray and other member functions which you explicitly or implicitly call in your generic algorithm will be generated for int, double, char and std::string template arguments. There's not much you can do to optimize it out of the executable.
However, what you can do is to decide how to store your object(s) in memory in most efficient way. And obviously for your task you need only a single instance of some simpleVector at a time. So you may think of a memory block big enough to keep any simpleVector instantiation and also designating which of them it currently contains. In C++ it will sound like this:
struct SimpleVectors {
VectorTypeEnum vte;
union {
simpleVector<int> v_int;
simpleVector<double> v_double;
simpleVector<char> v_char;
simpleVector<string> v_string;
};
};
Please note that you can do it only with POD-structures (google for the definition).
Inheritance-based approaches eventually boil-down to this kind of layout.
To complete the picture, we just need to connect a processing logic to this data structure:
template <
typename T
>
inline void handleTask (
simpleVector <
T
>
& v
)
{
int arraySize;
v.setDefaultArray();
cout << "Number of Inputs:";
cin >> arraySize;
v.setArraySize(arraySize);
v.fillArray();
}
The benefit of this approach over the inheritance-based is that you can make your class member functions inline, and the compiler will take care that their calls will be an order of magnitude faster than the virtual member functions.
And finally, the key piece of your main function will look as:
SimpleVectors userArray;
// we don't really need to initialize userArray.vte in this sample
if (dataType == "1" || dataType == "int") {
handleTask(userArray.v_int);
} else if (dataType == "2" || dataType == "double") {
handleTask(userArray.v_double);
} else if (dataType == "3" || dataType == "char") {
handleTask(userArray.v_char);
} else if (dataType == "4" || dataType == "string") {
handleTask(userArray.v_string);
}

Array based stack - error in destructor

This is my first pathetic attempt at C++. I did an array based stack in C++ and the destructor is throwing out some memory dump. I can't figure out what went wrong.
#include <stdio.h>
#include <iostream>
#include <exception>
using namespace std;
class FullStackException : public exception {
virtual const char* what() const throw() {
return "Stack is full.";
}
} fsex;
class EmptyStackException : public exception {
virtual const char* what() const throw() {
return "Stack is empty.";
}
} esex;
template <class D>
class ArrayBasedStack {
private:
int t; //t represents top
D *S;
int arrSize;
public:
ArrayBasedStack(int arraySize = 10);
~ArrayBasedStack();
int size(); /*returns the number of elements stored*/
void push(D&); /*inserts an element*/
D pop(); /*removes and returns the last inserted element*/
D top(); /*returns the last inserted element without removing it*/
int isEmpty(); /*indicates whether no elements are stored*/
};
template <class D>
ArrayBasedStack<D>::ArrayBasedStack(int arraySize) {
/* Elements are added from left to right */
S = new D[arraySize];
arrSize = arraySize;
/* t keeps track of the index of the top element */
t = -1;
}
template <class D>
ArrayBasedStack<D>::~ArrayBasedStack() {
if(S != NULL) {
int i = 0;
for(i = 0; i < size(); i++) {
S[i] = NULL;
}
cout << "about to delete S" << endl;
delete[] S;
}
}
template <class D>
int ArrayBasedStack<D>::size() {
return t;
}
template <class D>
void ArrayBasedStack<D>::push(D& data) {
if(t == arrSize) {
throw fsex;
} else {
S[t] = data;
t++;
}
}
template <class D>
D ArrayBasedStack<D>::pop() {
if(isEmpty()) {
throw esex;
}
D element = S[t];
S[t--] = NULL;
return element;
}
/*
* returns true if the stack is empty, false otherwise
*/
template <class D>
int ArrayBasedStack<D>::isEmpty() {
return (t < 0);
}
int main(int argc, char *argv[]) {
char inputs[][10] = {
"str1"
};
char *i = NULL;
ArrayBasedStack<char *> stack;
i = inputs[0];
stack.push(i);
try {
stack.pop();
}
catch(exception& ex) {
cout << "ERR:" << ex.what() << endl;
}
return 0;
}
The problem line is
t = -1;
Should be
t = 0;
because when you add first element, the following code is excecuted
} else {
S[t] = data; // t == -1
t++;
}
The following is the culprit.
template <class D>
void ArrayBasedStack<D>::push(D& data) {
if(t == arrSize) {
throw fsex;
} else {
S[t] = data; // Should be S[++t] = data;
t++; // Comment out this line
}
}
This implemntation assumes that 't' points to the topmost element on the stack rather than to the next available location for push
Note that operator [] and operator ++ have same precedence. Since they associate left-to-right, [] is evaluated before operator ++.
In your implementation, here is the problem. With t being initialized to -1, you are overwriting beyond the array subscript that is at S[-1] which leads to undefined behavior.
At least on my system the problem surfaces while trying to free the memory in destructor of the stack class. This is a classic example of a syptom being visible much after the goof-up has happened
Also would suggest push to take the parameters as D const &

Pointer to member functions - C++ std::list sort

How do i pass a pointer to a member function to std::list.sort()?
Is this possible? Thanks
struct Node {
uint32_t ID;
char * Value;
};
class myClass {
private:
uint32_t myValueLength;
public:
list<queueNode *> MyQueue;
bool compare(Node * first, Node * second);
bool doStuff();
}
bool myClass::compare(Node * first, Node * second) {
unsigned int ii =0;
while (ii < myValueLength)
{
if (first-> Value[ii] < second-> Value[ii])
{
return true;
} else if (first-> Value[ii] > second-> Value[ii])
{
return false;
}
++ii;
}
return false;
}
bool myClass::doStuff()
{
list.sort(compare);
}
I want to use a length variable from within the class instead of doing strlen() within the compare function (The Value will always be the same length)
Edit: The myValueLength was not the only variable i wanted to access from within the comparison function I just simplified it to make the example shorter.
Elaborating on grieve's response, why not use a functor? E.g.:
struct Functor
{
bool operator()( char * a, char * b )
{ return strcmp(a,b) < 0; }
};
Then you could just use:
Functor f;
myList.sort(f);
You could even use your class as the Functor by defining operator()...
class myClass {
...
bool operator()( queueNode * a, queueNode * b )
{ return compare( a, b ); }
void doStuff() { MyQueue.sort(*this); }
};
Simple example code:
#include <iostream>
#include <list>
using namespace std;
// Assumes TYPE t; cout << t; is valid.
template<class TYPE>
inline ostream & operator<< ( ostream & theOstream,
const list<TYPE> & theList )
{
typename list<TYPE>::const_iterator listIterator = theList.begin();
for ( int i = 0; listIterator != theList.end(); listIterator ++, i ++ )
theOstream << " [" << i << "]: \"" << (*listIterator) << "\"" << endl;
return theOstream;
}
struct Functor
{
bool operator()( const char * a, const char * b )
{ return strcmp(a,b) < 0; }
};
int
main()
{
list<char*> l;
/* Load up some example test data... */
char s[3];
s[2] = '\0';
for ( s[0]='c'; s[0]>='a'; s[0]-- )
for ( s[1]='c'; s[1]>='a'; s[1]-- )
l.push_back(strdup(s));
/* Show us that test data... */
cout << l << endl;
/* Sort list. */
Functor f;
l.sort(f);
/* Show us what we have now... */
cout << l << endl;
}
It is possible. Did you consider using boost::function?
list.sort( boost::bind( &myClass::compare, this, _1, _2 ) );
Is your 'compare' function will rely on this data? If not - you may simpy make 'compare' function to be static. And then it will be
list.sort( &myClass::compare );
You can add helper struct to do your comparison and then
list.sort( Comparer( myValueLength ) );
struct Comparer
{
Comparer( uint32_t myValueLength ):
length( myValueLength )
{}
bool operator() (Node * first, Node * second)
{
unsigned int ii =0;
while (ii < length)
{
if (first-> Value[ii] < second-> Value[ii])
{
return true;
} else if (first-> Value[ii] > second-> Value[ii])
{
return false;
}
++ii;
}
return false;
}
uint32_t length;
};
You may want to use a functor.
http://www.newty.de/fpt/functor.html
Note that std::list sorts the element according to operator< defined for that element. You need to change your compare function to use a global operator< defined for Node objects:
bool operator<(Node const& first, Node const& second) {
unsigned int ii =0;
while (ii < length)
{
if (first.Value[ii] < second.Value[ii])
{
return true;
} else if (first.Value[ii] > second.Value[ii])
{
return false;
}
++ii;
}
return false;
}
A suggested improvement will be:
bool operator<(Node const& first, Node const& second) {
for (size_t ii =0; first.Value[ii] == second.Value[ii]; ++ii) ; // note ;
return (first.Value[ii] < second.Value[ii]);
}
If char *Value really represents a C-style string, and you want lexicographic sorting, further improvements are possible:
bool operator<(Node const& first, Node const& second) {
return (strcmp(first.Value, second.Value) < 0);
}
and if they are really strings, I suggest you use std::string and you can write:
bool operator<(Node const& first, Node const& second) {
return first.Value < second.Value;
}
As grieve & mrree suggested
simply overloading the () operator works
Thanks everyone who answered
struct Node {
uint32_t ID;
char * Value;
};
class myClass {
private:
uint32_t myValueLength;
public:
list<queueNode *> MyQueue;
bool operator()(Node * first, Node * second);
bool doStuff();
}
bool myClass::operator()(Node * first, Node * second) {
unsigned int ii =0;
while (ii < myValueLength)
{
if (first-> Value[ii] < second-> Value[ii])
{
return true;
} else if (first-> Value[ii] > second-> Value[ii])
{
return false;
}
++ii;
}
return false;
}
bool myClass::doStuff()
{
list.sort(*this);
}
Why not make your compare function static then you no longer need the functor. Then you can simply do list.sort(compare);
nevermind ... i just realized your compare function is using a class data member so it cannot be static. Use Functor :)