How to check if two stacks are the same in C++? - c++

I am working with stacks and need to check to see if two are the same. I have overloaded the
bool operator==
function in my code, and now I need to put the logic in the code. I will check a few things to see if the two stacks are the same: the length, the data type, and the content of each element. Length and content are no problem, its the data type that is giving me issues.
I tried to make a function:
...
Type getType();
};
template <class Type>
Type getType(){ returnType;}
But this did not work.
I also thought about:
bool operator== (stack<Type> &lhs, stack<Type> &rhs){
return (lsh.Type == rhs.Type);
//additional conditions will be checked.
}
How to I check if they are the same type?
EDIT: What if I just checked the data type of the top elements of the two stacks? would that be sufficient?

If you implement operator== like this:
template<typename Type>
bool operator== (const stack<Type> &lhs, const stack<Type> &rhs){
// compare and return.
}
You already know that both stacks will contain elements of the same type. There's no need to check for that.
If you want to allow stacks using different template arguments to be compared, you could do something like this:
template<typename Type1, typename Type2>
bool operator== (const stack<Type1> &lhs, const stack<Type2> &rhs){
// compare
}
Then compare the elements using operator== and you'll be done. Of course, if there's no operator== for parameters of type Type1 and Type2, then the compiler will issue an error.
Edit: Since you want a nice error message, you could do this(using C++11):
#include <type_traits>
template<typename Type1, typename Type2>
bool operator== (const stack<Type1> &lhs, const stack<Type2> &rhs){
// This is a compile time assert!
static_assert(std::is_same<Type1, Type2>::value, "Types are not equal!");
// compare
}
I'd avoid this anyway. It's simpler to let the compiler issue its own error, rather than doing this check yourself.

C++ is not like other (dynamic) languages in that you do not need to check types. If two stacks contain different types, your code will not compile if you try to compare them. In other words, skip this step, the compiler will do it for you.

If you implement the stack data structure using templates (e.g. template <typename T> class Stack...), then you just need to overload operator== and check sizes and do an item-wise comparison:
template <typename T>
bool operator==(const Stack<T> & lhs, const Stack<T> & rhs)
{
if (lhs.Size() != rhs.Size())
return false;
// Compare item by item
...
}
The type will be implicitly checked by the C++ compiler type system (if you have a Stack<int> and try to compare against a Stack<string> you will have a compiler error).

I found a simple program which will solve your purpose, Its simple and very efficient way of checking if two stacks are equal or not.
bool isEqual(stack<Type> &stack1, stack<Type> &stack2) {
if (stack1.empty() && stack2.empty())
return true;
else if (stack1.empty() || stack2.empty())
return false;
while (!stack1.empty() && !stack2.empty())
{
if (stack1.top() != stack2.top())
return false;
stack1.pop();
stack2.pop();
}
if (stack1.empty() && stack2.empty())
return true;
else
return false;
}

As you can see in C++ tag definition of stackoverflow
C++ is a widely-used, statically-typed, free-form, compiled,
multi-paradigm, multi-level, imperative, general-purpose,
object-oriented programming language.
In this definition statically-typed mean all type information must be clean in compile time so in C++ if you want to have container of different types or you want to compare containers of different types, you must identify it in compile time through use of templates.
So when you are comparing 2 different type of containers (here stack) you know type of both containers and you do not need to compare their types. So if you want containers of different types, they should all derive from same class so they can stored as same type or you must hold them as void* (this is very dangerous unless you know what you are doing). in case that you derive all classes from same class, you can simply make base class polymorphic (by adding at least one virtual function) and use typeid to get type of object or you can add a virtual function that do comparison and then specialize it in each derived class (or even you can mix both techniques) but in case of void* you must have another way to identify type of objects!

Related

Should comparison be implemented under `compare` or `operator ==` when both are needed?

In making a class, the compare method and the operator== overload should have identical functionality. Therefore, only one implementation is needed, and I'm trying to figure out if there's any reason why it should be defined in the compare method rather than the operator== overload.
Here's the structure defining comparison in compare:
class T {
// definition of field f
...
bool compare(const T& t) const {
if (this->f == t.f) { return true; }
return false;
}
friend bool operator == (const T& lhs, const T& rhs) { return lhs.compare(rhs); }
}
versus in the operator == overloading:
class T {
// definition of field f
...
bool compare(const T& t) const { return *this == t; }
friend bool operator == (const T& lhs, const T& rhs) {
if (lhs.f == t.f) { return true; }
return false;
}
}
TL;DR use second variant with 'virtual' keyword, but it will be better to get rid of this bullshit at all and use operator== only
You should use method compare() only if you have other variant of objects comparison, otherwise it does not make any sense. The reason for this is implementation of std::map, std::set, sorting alghoritms, etc., which use operator==, so if you use first variation of == implementation it will be, basicaly, your operator==, but with other name, which does not make any sense.
If you still want to do it,
-You can use first variant(where == uses compare), but make compare method virtual. In this case you will be able to overload comparison method just like in Java and it will affect on comparison, but still you can do it just by creating operator== for children class, so it still doesn't make any sense
...or you can use second one, but still using 'virtual' keyword to change implementation of parent class in children classes and if you don't like == implementation you can use compare method
Not very relatable example, but I think it might help you. In OpenCV library assignment operator= for class Mat(this class contains literally array of pixels and nothing more) don't actually copies array, but copies only a pointer on array of pixels(because it's heavy operation and it doesn't required in many cases), and for actual copying method clone() used. I think you can use the same solution for your code

Using hash directly in methods from unordered_map instead of the user defined object producing the hash

So i have created a class that i use as a hash in an unordered_map
class MyClass
{
hash_type mHash = 0;
hash_type hash() { return mHash; }
bool operator!= (const MyClass& rhs) const;
bool operator== (const MyClass& rhs) const;
}
namespace std
{
template <>
struct hash<MyClass>
{
hash_type operator()(const MyClass& k) const noexcept
{
return k.hash();
}
};
}
It works as expected but i would like to add some functionality.
I would like to be able to use the hash itself when using unordered_map functions like find and erase.
Now i have to do this:
void _erase_key(const MyClass& key) { umap.erase(key); }
But i would like to be able to do this as well:
void _erase_key(const hash_type key) { umap.erase(key); }
Is it possible to somehow use the hash directly instead of the object producing the hash when using methods like find and erase?
If I understand you right, you want to have an std::unordered_map<MyClass, Value> such that you can also query with hash_type and you have hash_type h == MyClass m if std::hash<MyClass>{}(m) == h. Is this correct?
This is not possible in C++17. With C++20, there will be added the functionality of transparent hashes. You can read about that very briefly here. With this, your map has to fulfill certain properties
Your equality type Eq must provide a member type Eq::is_transparent, i.e. you have to put a using is_transparent = some_type; in it. (The exact type is without consequence.)
An object of type Eq has to provide an overload to compare all possible combinations of types you want to use. I.e. provide overloads for (MyClass, MyClass) and (MyClass, hash_type).
Your hash type Hash has to provide a member type Hash::transparent_key_equal, so again, put using transparent_key_equal = some_type; in it.
An object of type Hash must be callable with every type you want to use. I.e. you have to have an operator() overload for both MyClass and hash_type.
For Eq you can use std::equal_to<> (note the empty diamond!) if you provide publically accessible operator== for the appropriate types. This is NOT the default for unordered_map.
There is to the best of my knowledge no analagon for std::hash, so you have to add an own type for that and provide it to the map.
Pre-C++20 the only thing you can do if you want to keep your key type is to write a conversion from hash_type to MyClass.
But I sense a fundamental problem in this, namely that you see two objects of MyClass as identical if they have the same hash. If this is unintentional, you should really fix this. If it is intentional, make sure, that operator==(MyClass, MyClass) also only compares hashes.
In the later case, there is an easy fix for your problem. Change your map to std::unordered_map<hash_type, Value> and hash each MyClass you use to query the map. If you need a reverse lookup to get MyClass from a hash, either write a conversion function from hash_type to MyClass if this is possible, otherwise add another std::unordered_map<hash_type, MyClass>, where you store every object of type MyClass you ever use.

Generic operator== for non-pod objects

While doing some unit tests I want to be able to compare some pretty simple structs (they contain only public data members). I could write a operator== for all of them separately but it would be cumbersome and repetitive. So I decided to try to do this in a generic way. Yet there is a problem - some of them are not POD as some of their fields have non-POD type, let's say a std::list for an example.
struct NonPod {
std::list<int> lst;
};
struct NonPod2 {
std::list<NonPod> lst;
};
template<class T>
bool operator==(const T& lhs, const T& rhs) {
//what should I put here to make it work safely
//to compare NonPod with other NonPod
//ant NonPod2 with other NonPod2
}
AFAIK, to compare POD safely I could just use std::memcmp and it would be all fine. Is it possible to do generic operator== for non-POD types as well? If so, how?
Sadly, there is no way to do this in C++17 (or earlier). C++20 will allow you to add:
auto operator<=>(const class_name&) const = default;
to each class. This will give you all the comparison operators defined in the obvious way.
If the classes are being created by a code generator, then adding a comparison function should be easy.

Working with a secondary datastructure// Advice for data structure

I'm trying to build a Graph Datastructure based on an already existing Datastructure (which I cannot modify and which is not a graph itself).
I think I have somewhat a grasp on how to build most of the structure concerning the graph itself, but right now I have to reference back to the original data structure for one little "compare" function and having a really hard time how to model that properly...
My vertices represent two different classes A and B of the original data structure, that have different member variables and no common ancestors. For an algorithm I have to check whether two vertices are compatible.
The rule is: an A-Vertex and an B-Vertex are always incompatible, but if both vertices represent the same type I have to check some specifics for the respective type.
So the base idea is roughly like this:
bool isCompatible(const Vertex& other){
// if this->data is of other type than other->data
// return false;
// else return compareFunction(this->data, other->data)
// where maybe one could overload that compare-function
// or make a template out of it
}
But I don't really know how to store the reference to data without making it really ugly.
Idea 1) Use a void pointer for data, have some variable to store the type and then cast the void pointer into respective type
-> would probably work but seems really dangerous (type-safety?) and really ugly (basically no reusability for the Graph structure if you ever wanna use it on other data). Seems a bit like the brute force approach.
Idea 2) Make an abstract data class that offers some "isCompatible(data)" function, and have wrapper-classes for A and B respectively that inherit from the abstract class and override that function. Inside the overridden function one could use dynamic_cast then and compare the objects.
-> still doesn't seem like good design, but should also work?
Idea 3) Make templates work? It's my first time working with C++ so I'm having a few problems wrapping my head around that properly.
I think something like the following should work for comparing:
template<typename T1, typename T2>
bool compare(T1 object1, T2 object2){
return false;
}
And then having instances for (A,A) and (B,B) that override this. For me this seems like the way to got for the comparison itself. But I don't really know how to manage the reference from Vertex to the Object without losing the Type. Any suggestions?
I'm open to any other suggestions as well of course.
edit: I'm using C++11 if that's of relevance.
If your data is either an A or a B, where those two types have nothing in common, then sounds like what you want is a variant data type. The C++ standard library doesn't have one yet, but you could use Boost's:
boost::variant<A, B> data;
A variant gives you type safety (which void* doesn't) and doesn't require you to have a common ancestor between the two types (which apparently are conceptually unrelated).
With a variant like the above, you can implement your comparison using binary visitation:
bool isCompatible(const Vertex& other) {
boost::apply_visitor(is_compatible(), data, other.data);
}
with:
class is_compatible
: public boost::static_visitor<bool>
{
public:
template <typename T, typename U>
bool operator()( const T &, const U & ) const
{
return false; // cannot compare different types
}
bool operator()( const A& lhs, const A& rhs ) const
{
// whatever A-specific comparison
}
bool operator()( const B& lhs, const B& rhs ) const
{
// whatever B-specific comparison
}
};

when is better to use c++ template?

right now i am learning C++, and now I know the basic concept of template,
which act just like a generic type,
and i found almost every c++ program used template,
So i really want to know when are we supposed to use template ?
Can someone conclude your experience for me about c++ template ?
When will you consider to use template ?
Supplement:
if we defined such function
template <class myType>
myType GetMax (myType a, myType b) {
return (a>b?a:b);
}
but we want to pass a object(self-defined class) for comparison, how can we implement ?
Supplement2:
in the answer below, someone have wrote this sample code
template <class myType>
const myType& GetMax (const myType& a, const myType& b) {
return (a<b?b:a);
}
template <class myType, class Compare>
const myType& GetMax (const myType& a, const myType& b, Compare compare) {
return (compare(a,b)?b:a);
}
is this correct ? can we just pass a function name as a parameter of class myType ?
G'day,
Simple answer is when you want the behaviour to remain the same independent of the type being used to instantiate the class.
So a stack of ints will behave in the same way as a stack of floats will behave as a stack of MyClass objects.
Inheritance and base classes are used when you want to allow specialisation of the behaviour.
So say you have a base class called Animal and it has a member function called makeSound(). You have no idea which sound every animal will make so you make the makeSound member function a virtual function. In fact, because there is no default sound for all animals you have no idea what to have as default behaviour so you would declare this member function as a pure virtual function.
This then tells anyone making an instance of a derived class, for example a Lion class, that they must provide an implementation the makeSound member function which will provide a roar in some way.
Edit: I forgot to add that this is one of the articles in Scott Meyers's excellent book "Effective C++" (sanitised Amazon link) which I highly recommend.
HTH
cheers,
Basically when you want to create a generic class that can handle the solution for multiple types of classes, without having to have a parent-class for all the classes you want to support.
You can just give the class along with which you want to work with (best example would be a container, which can store any type that you pass along with the creation)
//----- the container
template <class T>
class Stack
{
public:
T* stackPtr;
}
//----- example
void main()
{
typedef Stack<float> FloatStack;
typedef Stack<int> IntStack;
}
Now you can store floats and ints with the same class without having to write a specific class for each type.
Short answer: if there is no use for it: don't.
If it seems to solve a problem (code reuse on different types,...), first implement and debug without templates and then add template parameters.
Before STL/boost, they were nice to make containers.
In the example you provided, everything is OK as long as operator > is defined for the data type whose instances you're comparing.
For example, if you define the following class:
class fraction
{
private:
int _num, _den;
public:
fraction(int num, int den)
{
if (den >= 0)
{
_num = num;
_den = den;
}
else
{
_num = -num;
_den = -den;
}
}
fraction(const fraction &f)
{
_num = f._num;
_den = f._den;
}
bool operator > (const fraction &f) const
{
return (_num * f._den) > (f._num * _den);
}
bool operator == (const fraction &f) const
{
return (_num * f._den) == (f._num * _den);
}
};
Then you can use your template function with instances of this class.
int main(int argc, char* argv[])
{
fraction a(1,2); // 0.5
fraction b(3,4); // 0.75
assert(GetMax/*<fraction>*/(a,b) == a);
return 0;
}
Re: supplement. If you want to pass a comparison function, you could provide another overload:
template <class myType>
const myType& GetMax (const myType& a, const myType& b) {
return (a<b?b:a);
}
template <class myType, class Compare>
const myType& GetMax (const myType& a, const myType& b, Compare compare) {
return (compare(a,b)?b:a);
}
Samle usage: to compare C-style strings:
bool c_strings_less(const char* a, const char* b)
{
return std::strcmp(a, b) < 0; //is a less than b
}
const char* greater = GetMax("hello", "world", c_strings_less);
This is how the std::max algorithm works. (I also made a few modifications, e.g it is customary in C++ that predicates define "less-than" comparison.)
Or if you asked, how GetMax would work for arbitrary user-defined types, then those must overload operator> or your function would result in a compile error.
When you need to parameterize concept represented by a class.
For example, if you have a class that represent a way to manage a type of object
class MyThingManager
{
void add( MyThing& mything );
//...
};
...maybe you need later to use exactly the same behaviour in a new type but managing a different type. Then you have the choice to use copy/paste/replace --that would lead hell opening under your feet immediately-- or make your class have a type to manage as parametter :
template< class ThingType >
class ThingManager
{
void add( ThingType& thing );
//...
};
That way you don't duplicate code.
Another concern is when you want some function call to be compatible with any parameter that have the required semantic :
template< class MyType >
void addPi( MyType& value )
{
value += PI;
}
That way you (again) don't have to duplicate code for each types possible in parametters.
It's not called "generic programming" for nothing.
Those are simple cases, but more complex cases exists, when you want to do some meta-programming. If you want to go there, please read at least one book before writing hell code. I recommand "C++ Template Meta-Programming" for that and the excellent "Modern C++ Design" book for more advanced template usage like Policy pattern ans other well known.
Answering the second question(
but we want to pass a object(self-defined class) for comparison, how can we implement?)
If you want to use your own class in a template function using the
operator >.
Your class need only to define this operator or function.
The important part is that your class need to define the same
the operator or function the template uses.
/Tobias
if you dont know the type of your variable or you want to do same thing for many types of variables, you can use template...
if you want to add 2 int, you want to get an int for return
if you want to add 2 double, you want to get an double for return
so you use template for this..
Template provide the way to parametrize on KNOWN AT COMPILE TIME quantities. Note that it can be a type (std::vector will contain only integers) but they can also be values:
template <int N, typename T > class MyType
is templatized both on an integer and a type, and MyType<2, int> will be a different type from MyType<3, int>.
Furthermore, templates allow for Template Metaprogramming: that is the compiler executes a program at compile time. There is a fascinating example by Erwin Unruh for computing primes at compile time.
Look at http://ubiety.uwaterloo.ca/~tveldhui/papers/priority.html for a small bit of history.
It's important to note that it's perfectly alright to not write your own templates. If you're not sure why you might need them, then you probably don't need them. Templates are a very powerful tool, but they are not always the best solution.
On any common development platform, the standard library provides a high-quality implementation of many of the old-school, traditional uses of templates. Using the standard library classes and functions doesn't require writing new templates. For instance, it provides std::max(), which is the same as your example.