c++ overloading function including bool and integer arguments - c++

a simple and I guess easy to answer question (if I did not already got it myself). The following overloaded functions:
void BR(const bool set) { backwardReaction_[nReac_] = set; }
bool BR(const int reactionNumber) const { return backwardReaction_[reactionNumber]; }
The first function is a setter and the second a getter function. backwardReaction_ is of type std::vector<bool>. The problem occurs whenever I want to call the second function. Here I get a compiler error overload function BR(xy) ambigious.
int main()
.
.
const int i = 3;
bool a = chem.BR(i);
The compiler error is equal to:
chemistryTestProg.cpp: In function ‘int main()’:
chemistryTestProg.cpp:74:34: error: call of overloaded ‘BR(const int&)’ is ambiguous
const bool a = chem.BR(i);
^
In file included from ../../src/gcc/lnInclude/chemistryCalc.hpp:38:0,
from ../../src/gcc/lnInclude/chemistry.hpp:38,
from chemistryTestProg.cpp:35:
../../src/gcc/lnInclude/chemistryData.hpp:266:18: note: candidate: void AFC::ChemistryData::BR(bool)
void BR(const bool);
^~
../../src/gcc/lnInclude/chemistryData.hpp:322:22: note: candidate: bool AFC::ChemistryData::BR(int) const
bool BR(const int) const;
^~
I guess that I get the problem because of the types bool and int which are identically (true => int(1), false => int(0). As I am changing the getter name to, e.g., bool getBR(const int reactionNumber) {...} everything works fine. So I guess the problem is about the similarities of the bool and int treatment within c++. I also tried a variety of different calls such as:
const bool a = chem.BR(4)
const bool a = chem.BR(int(5))
const bool a = chem.BR(static_cast<const int>(2))
bool a = chem.BR(...)
Thus, I think it is really related to the bool andint overloading arguments. Nevertheless, I made a quick search and did not find too much about these two overload types and resulting problems. Tobi

This is because you declared BR(int), but not BR(bool), to be const. Then when you call BR(int) on a non-const object, the compiler has two conflicting matching rules: parameter matching favours BR(int), but const-ness matching favours BR(bool).

Related

Intel TBB, exececute a member function with a parallel for

I have a class similar to this one:
struct orden
{
long long time;
double price;
const char* time1;
orden(const char* t, double p) : time1(t),price(p){};
void convertToMs()
{
time = dateToMs2(time1);
}
};
The what I'm doing is to read a file in serial, execute the constuctor of the struct and save the generated object in a vector of orden:
vector<orden> ord;
ifstream fe(filename)
while(getline(fe,order_line))
{
price = stod(order_line.substr(position+2));
time = order_line.substr(0,26).c_str();
ord.push_back(time, price);
}
Then, what I want to do in parallel is to execute the member function convertToMs(). But I have problems because the compiler ask me to execut only constant functions inside parallel for.
I have tryed some thinks that I have found like this one Without sucess because they are not saving the result of the execution in a parameter of the object.
What I'm doing wrong?
Thank you in advance
EDIT:
If I use
struct orden
{
long long time;
double price;
const char* time1;
orden(const char* t, double p) : time1(t),price(p){};
void convertToMs() const
{
time = dateToMs2(time1);
}
};
I have the following error:
In file included from pract1.cpp:5:0:
orden.h: In member function ‘void orden::convertToMs() const’:
orden.h:29:27: error: assignment of member ‘orden::time’ in read-only object
time = dateToMs2(time1);
If I delete the const i have the following one:
pract1.cpp: In lambda function:
pract1.cpp:158:43: error: passing ‘const value_type {aka const orden}’ as ‘this’ argument discards qualifiers [-fpermissive]
ordersOfTheCompany[j].convertToMs();
^
In file included from pract1.cpp:5:0:
orden.h:27:8: note: in call to ‘void orden::convertToMs()’
void convertToMs()
EDIT 2:
Sorry again, i have the folloging code:
vector<orden> ord;
while(getline(fe,order_line))
{
price = stod(order_line.substr(position+2));
time = order_line.substr(0,26).c_str();
ord.push_back(time, price);
}
tbb::parallel_for(tbb::blocked_range<size_t>(0,ord.size()),
[=](tbb::blocked_range<size_t>& r) {
for(std::size_t j=r.begin(); j!=r.end(); ++j)
{
ord[j].convertToMs();
}});
I'm trying to execute the member function in a parallel for
The documentation for parallel_for has an example similar to what you're trying to do. It saves the result into a separate array from the input array.
In your case, you'd want to add something like
std::vector<long long> outTime;
outTime.resize(ord.size());
right before the parallel_for call. Then, in the body of the lambda you execute, change the statement to
outTime[j] = ord[j].convertToMs();
after changing convertToMs to be a const function that returns the converted value rather than saving it locally. After the parallel_for returns, copy the results out of outTime back into ord.
You could have 2 versions of convertToMs, a non-const one that saves the result internally, and a const one that returns the converted time.

C++ BinarySearchTree Inserting an element

So I'm getting these errors when trying to insert to a binary search tree, I've literally been stuck on this one problem for hours not knowing what to do and I couldn't find anything on the internet to help so thanks in advance.
In file included from Indexer.h:19,
from Indexer.cpp:20:
BinarySearchTree.h: In member function ‘void BinarySearchTree<Comparable>::insert(const Comparable&, BinarySearchTree<Comparable>::BinaryNode*&) [with Comparable = Word]’:
BinarySearchTree.h:108: instantiated from ‘void BinarySearchTree<Comparable>::insert(const Comparable&) [with Comparable = Word]’
Indexer.cpp:109: instantiated from here
BinarySearchTree.h:165: error: passing ‘const Word’ as ‘this’ argument of ‘bool Word::operator<(Word&)’ discards qualifiers
BinarySearchTree.h:167: error: no match for ‘operator<’ in ‘t->BinarySearchTree<Word>::BinaryNode::element < x’
Word.h:33: note: candidates are: bool Word::operator<(Word&)
make: *** [Indexer.o] Error 1
And the Code I think is creating it is from Indexer.cpp line 109
Word takes in two parameters, current being the string and count is equal to 0 for this function.
Indexer.cpp
BinarySearchTree<Word> filterTree;
Line 109: filterTree.insert(Word(current, count));
BinarySearchTree.h
void insert( const Comparable & x )
{
Line:108 insert( x, root );
}
Word.cpp :operator<
bool Word::operator<(Word &RHS)
{
if(m_wordText < RHS.GetWord())
{
return true;
}
else
return false;
}
Member comparators should (almost) always be const functions that take const parameters,
bool Word::operator<(Word const&) const;
Any function called within a const function must also be const itself
std::string Word::GetWord() const;
(As #NeilKirk correctly points out this should probably return std::string const&).
You should learn about const correctness as it can stop you from making silly mistakes in your code.
Also using a non-member comparator is usually preferred as it allows both sides of the expression to use conversion operators
bool operator<(Word const& lhs, Word const& rhs)
{
return lhs.GetWord() < rhs.GetWord();
}

When to pass by reference for overloading operators in c++?

I have implemented a custom pointer class, lets call it japan. Here is a declaration and definition, as well as a main function I am trying to work with.
class japan
{
public:
japan(T *ptr) : ptr(ptr)
{}
T *get()
{
return this->ptr;
}
bool operator==(const T *&other)
{
return ( this->get() == other );
}
friend bool operator==(const T *&l, japan<T> r)
{
return ( r == l );
}
private:
T *ptr;
};
int main(void)
{
int j;
int *k = & j;
japan<int> nihon(k);
if(k == nihon)
if(nihon == k)
std::cout << "yay\n";
if(nihon == NULL)
return 1;
else
return 0;
if(NULL == nihon)
return 5;
}
My == operator seem to working fine on actual T *s when they are passed in, however if I evoke it with NULL my compiler produces the errors:
stuff.cpp:40:15: error: no match for 'operator==' in '0l == nihon'
stuff.cpp:40:15: note: candidate is:
stuff.cpp:21:16: note: bool operator==(const int*&, japan<int>)
stuff.cpp:21:16: note: no known conversion for argument 1 from 'long int' to 'const int*&'
From what I understand... there should be some form of conversion from T * to long int, or NULL's assignment operator would not function. I then reworked my operator a little.
Both of these functions work
friend bool operator==(T *l, japan<T> r);
friend bool operator==(const T *l, japan<T> r);
However This one fails.
friend bool operator==(const T *&l, japan<T> r);
This makes scene to me, changing NULL would change a value that is never used, but it is a const reference... so why does this fail. Is it common in c++ to not use references on boolean operators? Most of the examples I see always use a reference, but this seems like this would only work for lvalues... So is it better practice to pass by value while overloading?
ALSO:
Why would I get the warning :
warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: [enabled by default]
ptr.h:106:9: note: candidate 1: bool japan<T>::operator==(const T* const&) const [with T = Geometry]
stuff.cpp:239:15: note: candidate 2: operator==(int, long int) <built-in>
Is my japan class somehow exposing its self as a T when == is used, I ask this because I found this class in something I was working on with no == operator defined (despite it being used in many places), and I added one... only to find no end of problems.
In C++, 0 is an abused integer. It is used to reflect, well, 0 as a value of type int and it is also used to represent a null pointer.
Your types are fundamentally different. There's no const correctness issue, it's just that NULL, is a macro for 0 and that's something that doesn't cooperate well with generic programming. You could try
static_cast<T*>(NULL);
when comparing with null pointer, or better yet use nullptr, which is what the new standard wants you to be using when you mean "a null pointer"

How to pass a method to qsort?

There is a class that contains some data and it sorts them at some point of time. I use qsort() and I'd like to keep the comparing function within the class as a method. The question is how to pass a method to qsort() so that the compiler (g++) don't throw any warnings?
Attempt 1:
int Data::compare_records(void * rec_1, void * rec_2){
// [...]
}
void Data::sort(){
qsort(records, count, sizeof(*records), &Data::compare_records);
}
This way generates an error:
error: cannot convert ‘int (Data::*)(const void*, const void*)’ to ‘int (*)(const void*, const void*)’ for argument ‘4’ to ‘void qsort(void*, size_t, size_t, int (*)(const void*, const void*))’
Attempt 2 :
void Data::sort(){
qsort(
records, count, sizeof(*records),
(int (*)(const void*, const void*)) &Data::compare_records
);
}
This way generates a warning:
warning: converting from ‘int (Data::*)(const void*, const void*)’ to ‘int (*)(const void*, const void*)’
How to do it the right way then?
If you must use qsort and not std::sort (recommended), declaring the member method as static should be enough.
You pass the function as &Data::compare_records, but you should pass it as Data::compare_records and also make it static
Don't use qsort in C++. Use std::sort and boost/std::bind. Member function-pointer cannot been converted to function-pointer. Your method should be static, or it should be free function.
see Is the type of “pointer-to-member-function” different from “pointer-to-function”? for an explanation.
This code may also help as a hint, for std::sort despite the fact I Use Qt's qSort()
Functors can be very cool.
struct randomWSort
{
SatoshiGame* This;
randomWSort(SatoshiGame* g){This=g;}
bool operator()(QString& a, QString& b)
{
return This->randomWSort(a,b);
}
};
bool SatoshiGame::randomWSort(QString& a, QString& b)
{
return rand->rnd() %2;
}
QString SatoshiGame::getRandomString(QStringList words)
{
qSort(words.begin(), words.end(), ::randomWSort(this) );
return words.at(0);
}

2 overloads have similar conversions

A similar question to this
C++ Function Overloading Similar Conversions
has been asked and i understand the general premise of the problem. Looking for a solution.
I have 2 overloaded functions:
virtual IDataStoreNode* OpenNode(const char *Name, bool bCreateIfNotExist,int debug=0) { return 0;
}
virtual IDataStoreNode* OpenNode(const char* Name,int debug=0) const { return 0; }
From the errors it would appear that bool and int cannot be used to distinguish function overloads.
The question is , is there a way to work around this?
bool and int can be used to distinguish function overloads. As one would expect, bool arguments will prefer bool overloads and int arguments - int overloads.
Judging by the error message (I assume that the title of your question is a part of the error message you got), what you are dealing with is the situation when the argument you supply is neither bool nor int, yet conversions to bool and int exist and have the same rank.
For example, consider this
void foo(bool);
void foo(int);
int main() {
foo(0); // OK
foo(false); // OK
foo(0u); // ERROR: ambiguous
}
The first two calls will resolve successfully and in expected manner. The third call will not resolve, because the argument type is actually unsigned int, which however supports implicit conversions to both bool and int thus making the call ambiguous.
How are you calling your functions? Show us the arguments you are trying to pass.
For the following functions:
virtual IDataStoreNode* OpenNode(const char *Name, bool bCreateIfNotExist,int debug=0) { return 0; }
virtual IDataStoreNode* OpenNode(const char* Name, int debug=0) const { return 0; }
The following call (as an example, there might be others) would be ambiguous:
unsigned int val = 0; //could be double, float
OpenNode("", val);
Since a unsigned int can be converted to both bool and int, there is ambiguity. The easiest way to resolve it is to cast the parameter to the type of the parameter in your preferred overload:
OpenNode("", (bool)val);
OR
OpenNode("", (int)val);