Error in custom struct set declaration - c++

I'm getting a weird compiler error and as I'm new to using set's with custom struct's I'm not sure what exactly the problem is.
I'm trying to create a set of "pair's" and am using a custom comparison function for inserting said pair's.
struct pairT {
std::string first, second;
};
int PairCmp(pairT &one, pairT &two) {
if (one.first < two.first && one.second == two.second) return 0;
else if (one.first < two.first) return -1;
else if (one.first == two.first && one.second < two.second) return -1;
return 1;
}
std::set<pairT> CartesianProduct (std::set<std::string> &one, std::set<std::string> &two) {
std::set<pairT> returnSet(PairCmp);
/.../
I'm getting the error from the last line of code:
C2664 "can't convert parameter 1 from int to const std::less... blah, blah, blah.
Any suggestions as to why I'm getting my ass kicked?

Using objects (instead of pointers) requires that you name a second template parameter for std::set used to compare two objects of pairT. See std::less<> for an example.
Also, what you're trying here seems to be wrong. You're trying to return a std::set in CartesianProduct(), but the returned PairCmp() returns an integer.

Related

How do I return an error when the error type of a function is different?

I am writing a vector class that uses templates so that it can support multiple data types being stored within it. I have a function called get() which returns a specific index within the vector.
MyVector.h
template<class type>
class MyVector {
/* Stuff to make the vector work with features such as pushing back...*/
type get(int index) {
if (index < 0 || index > this->size) {
/* Make the compiler recognize this as a compile error and return
an error message of my choice
*/
return type{};
}
return this->data[index];
}
};
My first question here is how do I make the compiler stop and recognize this as an error and fail to compile. In addition to failing to compile, the compiler should print some error message like Index out of range or something like that. Is this possible within C++?
My second question here is why return type{} actually works (I had to return something, and I just randomly tried return type{}).
In addition, I am trying to use operator overloading so that I can access elements of the vector class with ease. The operator overloading function should return a reference to the element being returned, so that I can change it.
Like vector[index] = value.
The following is my function
type& operator[](int index) {
if (index < 0 || index > this->size) {
/* Make the compiler recognize this as a compile error and return
an error message of my choice
*/
return type{};
}
return this->data[index];
}
I have the same question as above, namely, how do I make the compiler fail to compile and print an error message. Also, what am I supposed to return in this situation? Is there any way I can avoid returning altogether?

Looking for any way to increment ENUM type without operator overloading

so this is about an assignment.
I have a header file with predefined ENUM type (TDay) which I CANNOT change in any way. TDay does not support any operator other than streams.
My problem is I need to find a way to do something like this:
Object::Object (uint aSize) {
Object temp; // contains varible inicialized to zero, this variable can be bool, int, RGB structure
// or TDay enum. I also can't use templates here.
for (int i = 0; i < aSize; i++) {
this->array[i] = temp.Value() + 1; // array is of the same type as Value
}
}
This code is just for illustration of what I need to do, don't look for any use of this I just made it up just to better explain my problem.
So anyway this doesn't work because my TDay doesn't support TDay+int operator.
Is there any way around this? Solution doesn't have to be clean, I'll accept any pointer cheats.
EDIT:
So I tried putting in my Object.cpp file this:
TDay operator+(TDay aDay, int aValue) {
return static_cast<TDay>(int(aDay) + aValue);
}
And it doesn't work. Compiler error says:
Argument of type int is imcompatible with parameter of type TDay
However if I put this code to TDay.h it works fine. Is something wrong with my linker?
I would create a function taking current ENUM value named for example increase
void increase(your_enum& e){
if(e == e::MAX_VAL)
e = e::MIN_VAL; //if you have it, otherwise do same as below
else{
int val = int(e); //cast it to int
val++;
e = static_cast<your_enum>(val); //cast it back
}
}
Creating a function taking another parameter to increase/decrease by more than one should be easy from this point.

String array to C++ function

I want to check if a given name is inside an array of possible names. I wrote this small debugging function ( yeah... I know it always return true ) trying to understand why it does not work and why I get the below error.
Code
char[] people_names = ["Mario","Luigi"];
bool lookupTerm (string term, string possible_names[]){
for(const string &possible_name : possible_names)
cout << possible_name << endl;
return true;
}
Error
jdoodle.cpp: In function 'bool lookupTerm(std::__cxx11::string, std::__cxx11::string*)':
jdoodle.cpp:19:38: error: no matching function for call to 'begin(std::__cxx11::basic_string<char>*&)'
I know that it must be really obvious but according to what I have searched for, it should work. Can someone point me in the right direction?
The problem is that when you pass an array to a function, it decays to a pointer to its first element.
It doesn't matter if you attempt to declare the argument as an array, the compiler still translates it as a pointer. string possible_names[] is equal to string* possible_names when you declare arguments.
The simple solution is to use either std::vector or std::array depending on your needs and use-case.
Using std::vector your code would look something like this:
std::vector<std::string> people_names = { "Mario", "Luigi" };
bool lookupTerm(const std::string& term, const std::vector<std::string>& possible_names) {
for (const std::string &possible_name : possible_names)
{
if (possible_name == term)
return true;
}
return false;
}
One line using std::find:
bool lookupTerm(const std::string& term, const std::vector<std::string>& possible_names) {
return std::find(possible_names.begin(), possible_names.end(), term) != possible_names.end();
}
If performance becomes a problem you can increase the performance of this by using a sorted vector (using std::sort) and std::lower_bound:
//at one point:
std::sort(people_names.begin(), people_names.end());
bool lookupTerm(const std::string& term, const std::vector<std::string>& sorted_possible_names) {
//sorted_possible_names must be always sorted when you call this!
auto i = std::lower_bound(sorted_possible_names.begin(), sorted_possible_names.end(), term);
return (i != sorted_possible_names.end() && *i == term);
}

Check if function declared after Template first Argument is NULL (Passing Vector & Array)

While working with one of my other projects I came across what I believed to be an overloading error. I opened a new project, researched about overloading and here is quick code:
#include <iostream>
#include <vector>
#include <string>
template<class T, class A>
void template_Function(T first_Arg, A second_Arg)
{
if (first_Arg == NULL){
std::cout << "First argument of the template function is null." << std::endl;
std::cin.get();
return;
}
int main()
{
//Declare and assign values to vector.
std::vector<std::string> my_Vector;
my_Vector.push_back("Hello, Friend");
//Declare and assign values (using for loop) to array.
int my_Array[10];
for (int i = 0; i < 10; i++)
{
my_Array[i] = i;
}
//Attempting to pass BOTH the vector and array to the template function.
template_Function(my_Vector, my_Array);
std::cin.get();
return 0;
}
If I run this I get the error code C2678: binary '==' etc. I solved that issue by including these lines of code:
template<class T, class A>
void operator==(const T &q, const A &w);
Right after I included the headers. The new error states,
error C2451: conditional expression of type 'void' is illegal c:\users\axiom\documents\visual studio 2013\projects\_test_template\_test_template\source.cpp 11 1 _test_Template
I THINK it means, from all the googling that I can't compare "first_Arg" with NULL. Which is pretty much what I'm trying to do, see if the first_Arg is null and then go from there.
Thank you for any assistance.
You are passing a value-type (vector) to a function, but then try & compare it with a pointer (NULL). That can't work.
So either you declare your function to take a parameter T*, forcing you to pass my_Vector using &my_Vector, or you switch to reference semantics (const if you like), and don't compare with NULL at all.

How Do I Search For Struct Items In A Vector?

I'm attempting to create an inventory system using a vector implementation, but I seem to be having some troubles. I'm running into issues using a struct I made. NOTE: This isn't actually in a game code, this is a separate Solution I am using to test my knowledge of vectors and structs!
struct aItem
{
string itemName;
int damage;
};
int main()
{
aItem healingPotion;
healingPotion.itemName = "Healing Potion";
healingPotion.damage= 6;
aItem fireballPotion;
fireballPotion.itemName = "Potion of Fiery Balls";
fireballPotion.damage = -2;
vector<aItem> inventory;
inventory.push_back(healingPotion);
inventory.push_back(healingPotion);
inventory.push_back(healingPotion);
inventory.push_back(fireballPotion);
if(find(inventory.begin(), inventory.end(), fireballPotion) != inventory.end())
{
cout << "Found";
}
system("PAUSE");
return 0;
}
The preceeding code gives me the following error:
1>c:\program files (x86)\microsoft visual studio
11.0\vc\include\xutility(3186): error C2678: binary '==' : no operator found which takes a left-hand operand of type 'aItem' (or there is no
acceptable conversion)
There is more to the error, if you need it please let me know. I bet it's something small and silly, but I've been thumping at it for over two hours. Thanks in advance!
find looks for something that's equal to the item in the vector. You say you want to search using strings, but you haven't written code for that; it's trying to compare the entire struct. And you haven't written code to compare entire structs, so it's giving you an error.
The simplest solution is to use an explicit loop instead of find.
If you want to find things by string, use the find_if variant and write a predicate function that looks at the string. Or if you want to find things by the entire struct you can define an operator == on the struct that compares both itemName and damage.
Or you might also consider using the map or unordered_map data structures instead of vector. The map containers are designed for fast lookup using a key (such as the string).
The find method does not know how to compare two aItem objects for equality. You need to define the == operator in your struct definition, like this:
bool operator==(aItem other)
{
if (itemName == other.itemName && damage == other.damage)
return true;
else
return false;
}
This will allow find to determine if two aItem objects are equal, which is necessary for the algorithm to work.
try something like:
#include <iostream>
#include <vector>
using namespace std;
struct item {
item(string const name,int const damage):name_(name),damage_(damage) {
}
string name_;
int damage_;
};
int main(int argc, char** argv) {
vector<item *> items;
item healingPostion("cure light",-10);
item fireballPostion("fireball",10);
items.push_back(&healingPostion);
items.push_back(&fireballPostion);
if(find(items.begin(), items.end(), &fireballPostion) != items.end()) {
cout << "Found";
}
return 0;
}