error: passing ‘const Integer’ as ‘this’ argument of ‘Integer Integer::pow(int)’ discards qualifiers - c++

I have Integer class that is supposed to simulate an integer mod n. Thus, it has constructors like:
Integer::Integer(int x)
: m(x), n(0)
{
}
Integer::Integer(int x, int y)
: n(y), m(x)
{
// if this->n greater than 1
if (this->n > 1)
{
// mod this->m by this->n
this->m %= this->n;
// if this->m is negative
if (this->m < 0)
{
// add this->n to it
this->m += this->n;
}
}
}
There is also Integer::inverse(), Integer::pow(int), which are needed for completeness of this question:
Integer Integer::inverse()
{
// Extended Euclidean Algorithm
int t = 0,
r = this->n,
newT = 1,
newR = this->m;
while (newR != 0)
{
int quotient = r / newR,
tCopy = t,
rCopy = r,
newTCopy = newT,
newRCopy = newR;
t = newT;
newT = tCopy - quotient * newTCopy;
r = newR;
newR = rCopy - quotient * newRCopy;
}
if (r > 1)
{
throw Integer(-1);
}
if (t < 0) t = t + this->n;
return Integer(t, this->n);
}
Integer Integer::squared()
{
return Integer(this->m * this->m, this->n);
}
Integer Integer::pow(int x)
{
// if x less than 0, return this->inverse().pow(-x)
if (x < 0) return this->inverse().pow(-x);
// if x is 0, return Integer(1)
if (x == 0) return Integer(1, this->n);
// if x is 1, return *this
if (x == 1) return *this;
// if x is 2, return this->squared()
if (x == 2) return this->squared();
// if x greater than 2
if (x > 2)
{
// if x is even
if (x % 2 == 0)
{
// return this->pow(x/2).squared()
return this->pow(x/2).squared();
}
// return this->pow(x/2).squared() * (*this)
return this->pow(x/2).squared() * (*this);
}
}
Problem I'm having is when I go to implement Integer::isQuadraticResidue() const:
bool Integer::isQuadraticResidue() const
{
// if this->n is zero
if (this->n == 0)
{
// this doesn't belong to Integers mod anything. check for perfect square instead
double baseSquareRoot = std::sqrt((double)this->m);
return (baseSquareRoot == (double)((int)baseSquareRoot));
}
// this is quadratic residue iff this->pow((this->n + 1) / 2) == Integer(1, this->n)
return (this->pow((n + 1) / 2).m == 1);
}
I get following error: error: passing ‘const Integer’ as ‘this’ argument of ‘Integer Integer::pow(int)’ discards qualifiers. I think it has everything to do with the const on the end. What do?
EDIT: Class header file looks something like:
#ifndef INTEGER_H
#define INTEGER_H
#include <iostream>
class Integer
{
public:
Integer(int);
Integer(int, int);
// functions
Integer inverse();
Integer squared();
Integer pow(int);
bool isQuadraticResidue() const;
Integer sqrt();
private:
int m, n;
};
#endif

This is an issue with const correctness, where a const function is trying to call a non-const function.
// ...
bool Integer::isQuadraticResidue() const;
Integer Integer::pow(int x);
// ....
In this situation, this is an Integer* in pow(), and a const Integer* in isQuadraticResidue(); this means that pow() can call isQuadraticResidue(), because it's legal to add CV-qualifiers, but not the other way around (because pow() would have to accept this as a non-qualified Integer*, losing the const qualifier).
This is unallowed, because allowing it would mean that isQuadraticResidue() breaks its guarantee that it won't modify the instance, whether directly or indirectly. While it itself doesn't change state, it assumes that pow() does change state, because pow() isn't also const (and thus doesn't promise not to change state). Due to this, isQuadraticResidue() is unable to call pow(), because doing so would risk breaking its guarantee.
Considering that, there are two solutions for this issue.
Remove const from isQuadraticResidue(). This would naively solve the problem, but isn't recommended, because then you wouldn't be able to reap the benefits of const correctness.
Make all member functions that don't modify Integer's logical state const, as well. This will require a bit more effort, but is overall safer. As they can then be called on a const Integer just as well as they can on an Integer, you will then be able to pass your instances around as const whenever they don't need to be modified, giving you a greater degree of safety.
Integer Integer::inverse() const;
Integer Integer::squared() const;
Integer Integer::pow() const;
This will need to be changed both in the functions' prototypes, and in their definitions.

the problem maybe you declared pow's this as non-const and trying to invoke it from isQuadraticResidue()const so in c++ it is not allowed to do so:
const this calls only member function whose this is const
you should either make pow's this const and as I guess it is bad idea becuase maybe you want to change some member data in it.
otherwise make isQuadraticResidue's this non-const
Integer pow(int x); // this is non const
bool isQuadraticResidue(); // this is not const
now everything is ok. as you can see after adding class declaration we get the error where!

Related

Specification of lambda's return value doesn't work

I've got a problem.
The funciton "__sub" parses a string like "1x + (5y - 2)". Each time it sees "(", it calls itself to parse exactly what is in parenthesis.
Here is some pseudocode, illustrating the problem:
auto __sub = [&needed_fn](const char *& iter, char end_at) -> int {
for (; *iter != end_at; iter++) {
if () {
int number = needed_fn(iter);
} else if (*iter == '(') {
int sub_result = __sub(iter, ')');
}
}
return 0; // temporarily, as for debugging purposes only needed
};
But this doesn't work. At first there was no specification of (-> int).
And it doesn't work in both cases with or without that specification of the return value.
It says:
a.cpp: In lambda function:
a.cpp:97:22: error: use of ‘__sub’ before deduction of ‘auto’
int sub_result = __sub(it, ')');
Suggestion: define __sub as a std::function<int(const char *, char)>
std::function<int(const char * &, char)> __sub;
__sub = [&needed_fn](const char *& iter, char end_at) -> int {
for (; *iter != end_at; iter++) {
if ( /* ??? */ ) {
int number = needed_fn(iter);
} else if (*iter == '(') {
int sub_result = __sub(iter, ')');
}
return 0;
};
otherwise the compiler can't deduce (auto) the type of __sub() using the same __sub() inside the body of __sub().
I'm going to disagree with the assertion that it is a chicken and egg problem, or it is at least a solvable one, and suggest instead that this is a quirk of the language, because you can accomplish virtually the same thing by hand.
To slightly simplify the discussion, take a common recursive example, factorial (godbolt):
auto factorial = [](int n) {
if (n == 0)
return 1;
else
return n * factorial(n - 1);
};
It fails with the error you see:
<source>: In lambda function:
<source>:7:24: error: use of 'factorial' before deduction of 'auto'
7 | return n * factorial(n-1);
| ^~~~~~~~~
But factorial is a variable of automatic storage duration, so you cannot refer to it without capturing it, and the code must be incorrect without a capture. Capturing by value doesn't make sense, as the lambda type would contain a copy of itself. That would be inconsistent with typical C++ classes which cannot contain copies of themselves, even if otherwise empty. Thus, one must capture by reference (godbolt):
auto factorial = [&factorial](int n) {
if (n == 0)
return 1;
else
return n * factorial(n - 1);
};
Our code is now more correct. What does the compiler say?
<source>:3:24: error: use of 'factorial' before deduction of 'auto'
3 | auto factorial = [&factorial](int n) {
| ^~~~~~~~~
<source>: In lambda function:
<source>:7:24: error: use of 'factorial' before deduction of 'auto'
7 | return n * factorial(n - 1);
| ^~~~~~~~~
More errors! A lambda is just syntactic sugar for a function object, so let's take a step back and see if the unsugared form would just work (godbolt):
struct factorial_t
{
factorial_t& factorial;
auto operator()(int n) const
{
if (n == 0)
return 1;
else
return n * factorial(n - 1);
}
};
int main()
{
factorial_t factorial{factorial};
}
That works, and in a perfect world, maybe the lambda form would too. Before the auto in factorial is deduced, it is very much like an incomplete type. References and pointers to incomplete types are allowed in C++ including those to a class or struct which contains them. And lambda reference captures are just references or pointers. So this is all possible within the spirit of the language. A different language could deduce the type of factorial to the type of the lambda, while the lambda type is incomplete, i.e. before attempting to create a definition for the lambda type.
In C++, you have a few possible solutions. First, you can write the closure type by hand (as in the third example).
Second, you can erase the type, as in the other answer (godbolt):
std::function<int(int)> factorial = [&factorial](int n) {
if (n == 0)
return 1;
else
return n * factorial(n - 1);
};
Note that the other answer was missing the capture which is key.
Third, you can delay the need for the type (godbolt):
auto factorial = [](int n, auto&& factorial) {
if (n == 0)
return 1;
else
return n * factorial(n - 1, factorial);
};
That delays the need for the type by making the call operator a template, at the cost of an awkward usage, e.g. factorial(4, factorial). Even that is surmountable with a small level of indirection (godbolt):
auto factorial_impl = [](int n, auto&& factorial_impl) {
if (n == 0)
return 1;
else
return n * factorial_impl(n - 1, factorial_impl);
};
auto factorial = [&factorial_impl](int n) {
return factorial_impl(n, factorial_impl);
};
Hope this helps!

Static array size determined from template values

I'm trying to use static array which size needs to be determined by given template values. However size will be constant across program runtime - thats why I decided not to use std::vector.
template<uint32_t BAR_WIDTH>
class Bar
{
//do_stuff...
Foo mapper[ [&]()->int{ uint32_t tmp = BAR_WIDTH / Foo:FOO_EDGE; return (BAR_WIDTH % 10 == 0) ? tmp : tmp + 1; }; ];
};
FOO_EGDE is const static value. IDE gives me a hint that
Array size expression must have an integer type instead of int(*)()
I wonder if I can make it work this way without using std::vector. Any advice is welcomed and appreciated.
The problem is, that you are using a lambda for determining the size of the array. If you leave it off and just use the ternary operator, it works:
int main() {
const bool z = true;
const int x = 5, y = 3;
int arr[z ? x : y];
return 0;
}
Ideone
As opposed to:
int main() {
const bool z = true;
const int x = 5, y = 3;
int arr[[&]() -> int { return z ? x : y; }];
return 0;
}
Ideone
As described here, lambda expressions can't be constexpr yet, and you can only declare the size of an array with a constexpr value (even then, you are not trying to invoke declared lambda (to invoke it - () is required at the end of declaration).
To work around such problem, you could use a private static constexpr method, and use the return value of it, for the array size declaration:
static constexpr uint32_t GetArraySize ()
{
uint32_t tmp = BAR_WIDTH / Foo::FOO_EDGE;
return (BAR_WIDTH % 10 == 0) ? tmp : tmp + 1;
}
Foo mapper[GetArraySize ()];

Return from calling function inside lambda

Lambdas are an awesome way to create reusable code inside a function/method without polluting the parent class. They're a very functional replacement for C-style macros most of the time.
However, there's one bit of syntactic sugar from macros that I can't seem to replicate with a lambda, and that's the ability to exit from the containing function. For example, if I need to return while checking the range of a series of ints, I can do that easily with a macro:
const int xmin(1), xmax(5);
#define CHECK_RANGE(x) { if((x) < xmin || (x) > xmax) return false; }
bool myFunc(int myint) {
CHECK_RANGE(myint);
int anotherint = myint + 2;
CHECK_RANGE(anotherint);
return true;
}
Obviously this is an oversimplified example, but the basic premise is that I'm performing the same check over and over on different variables, and I think it's more readable to encapsulate the check and related exits. Still, I know that macros aren't very safe, especially when they get really complex. However, as far as I can tell, trying to do the equivalent lambda requires awkward additional checks like so:
const int xmin(1), xmax(5);
auto check_range = [&](int x) -> bool { return !(x < xmin || x > xmax); };
bool myFunc(int myint) {
if(!check_range(myint)) return false;
int anotherint = myint + 2;
if(!check_range(anotherint)) return false;
return true;
}
Is there a way to do this with a lambda? Or am I missing some alternative solution?
Edit: I recognize that returning from inside a macro is generally a bad idea unless significant precautions are taken. I'm just wondering if it's possible.
You are correct--there's no way to return from the caller from inside a lambda. Since a lambda can be captured and stored to be called later, from inside an arbitrary caller, doing so would result in unpredictable behavior.
class Foo
{
Foo(std::function<void(int)> const& callMeLater) : func(callMeLater) {}
void CallIt(int* arr, int count)
{
for (index = count; index--;)
func(count);
// do other stuff here.
}
std::function<void(int)> func;
};
int main()
{
auto find3 = [](int arr)
{
if (arr == 3)
return_from_caller; // making up syntax here.
};
Foo foo(find3);
};
Is there a way to do this with a lambda?
Not exactly like the macro but your lambda, instead of returning a bool, can throw a special exception (of type bool, by example)
auto check_range
= [](int x) { if ( (x < xmin) || (x > xmax) ) throw bool{false}; };
and the function myFunc() can intercept this special type
bool myFunc (int myint)
{
try
{
check_range(myint);
int anotherint = myint + 2;
check_range(anotherint);
return true;
}
catch ( bool e )
{ return e; }
}
For a single check_range() call, this is (I suppose) a bad idea; if you have a lot of calls, I suppose can be interesting.
The following is a full working example
#include <iostream>
constexpr int xmin{1}, xmax{5};
auto check_range
= [](int x) { if ( (x < xmin) || (x > xmax) ) throw bool{false}; };
bool myFunc (int myint)
{
try
{
check_range(myint);
int anotherint = myint + 2;
check_range(anotherint);
return true;
}
catch ( bool e )
{ return e; }
}
int main ()
{
std::cout << myFunc(0) << std::endl; // print 0
std::cout << myFunc(3) << std::endl; // print 1
std::cout << myFunc(7) << std::endl; // print 0
}
No better way to do this than just to use the return value of the lambda and then return from the calling function. Macros are ew for this.
As it stands in C++, that is the idiomatic way to exit from a function that uses another condition to determine whether or not to exit.
Not C++11, but people have hacked C++2a coroutines to basically do this.
It would look a bit like:
co_await check_range(foo);
where the co_await keyword indicates that in some cases, this coroutine could return early with an incomplete result. In your cases, this incomplete result would be non-resumabable error.
The playing around I saw was with optionals, and required using a shared ptr, but things may improve before it is standardized.

Prevent a returning function from execution if a condition on parameters is true

like said on the title, I was wondering if it was possible to stop a function from execution. In my particular case, I'm trying to make an operator[] and prevent utilisator from using it if the value gave in parameters is too high :
in .h:
class Vec4
{
float x,y,z,w;
public:
float operator[](const unsigned int i);
}
in .cpp :
float Vec4::operator[](const unsigned int i)
{
if(i == 0) return x;
if(i == 1) return y;
if(i == 2) return z;
if(i == 3) return w;
}
I'd like to "break" the function if i >=4
For the moment I'm just making a console output and return 0.0f
thank you to show me if there is a way ... or not !
You can do at least 4 things.
Return a known error value from the function. For eg. -1 if the input value is no good.
Raise an exception.
Change the function to pass output by reference and return an error code.
Force the user to get the point with a strongly typed enum class.
Option 1
float Vec4::operator[](const unsigned int i) {
switch (i)
case 0:
return x;
...
default:
return nan;
Option 2
default:
throw InvalidInputException;
Option 3
typedef ErrCode int;
const int ERROR = -1;
const int SUCCESS = 1;
...
ErrCode Vec4::getPoint(const unsigned int i, float &ouptut) {
...
switch (i)
case 0:
output = x;
return SUCCESS;
default:
return ERROR;
Option 4 (c++11)
class Vec4 {
...
public:
enum class VecMem {X, Y, Z, W};
float Vec4::getPoint(VecMem member) {
switch (member):
case X:
return x;
...
Usage:
Vec4.getPoint(Vec4::VecMem::X);
Use "switch case " and for the case where value is différent bigger than 3 return a default state which can be a specific value reserved for this case
If your argument is known during the compilation, you can use a static_assert.
#include <cassert>;
constexpr float Vec4::operator[](const unsigned int i)
{
static_assert(i <= 3);
...
}
Static assertions are not impacting performance as they are checked during the compilation.
If your argument isn't known during the compilation, you can use dynamic assert.
#include <cassert>;
float Vec4::operator[](const unsigned int i)
{
assert(i <= 3);
...
}
Dynamic assertions are contained in compiler output only after setting compiler flags that enable them, so can be switched off easily.
Or you can just throw an exception.
float Vec4::operator[](const unsigned int i)
{
if (i > 3)
{
throw BadArgumentException("i must be <= 3");
}
...
}
Exceptions can contain a lot of information and be handled in other parts of the code, but have the biggest performance cost.
http://en.cppreference.com/w/cpp/error/assert
If you don't mind using upcoming features, you can use std::optional to do that:
std::optional<float> Vec4::operator[](const unsigned int i) {
if(i == 0) return x;
if(i == 1) return y;
if(i == 2) return z;
if(i == 3) return w;
return {};
}
The drawback is that the caller must check the validity of the returned value (using either the operator bool or the has_value member function) or use the value_or member function to get a default value for empty optionals.

Having issues with overloading C++ operators

I'm having some issues understanding this concept. In the main.cpp file, we have a function as follows:
void TestComparison()
{
MyFloat X, Y;
cout << "\n\n============ Testing \"==\" for MyFloat ================\n";
do
{
cout << "\nEnter X ==> ";
X.Read();
cin.ignore(1000, '\n'); // Discard all chars in input stream.
cout << "\nEnter Y ==> ";
Y.Read();
cin.ignore(1000, '\n'); // Discard all chars in input stream.
cout << "\n\n";
if ( X == Y )
{
X.Write(); cout << " is equal to "; Y.Write();
}
else
{
X.Write(); cout << " is NOT equal to "; Y.Write();
}
}
while ( SpaceBarToContinue() );
}
This is the class I'm writing:
class MyFloat
{
enum {MAXDIGIT=20};
char Number[MAXDIGIT+1];
char NumberOfDigits;
public:
friend void AssignValue(MyFloat& X);//remove after the program works
MyFloat();
int Digits();
int MaxDigits();
void Read();
void Write();
MyFloat operator + (MyFloat x);
int operator== (MyFloat x);
};
Here is my == overload function stub:
int MyFloat::operator== (MyFloat x)
{
int Flag=0;
return 1;
}
The only purpose of this is to compare two an array of objects X and Y. They are passed into a == overloaded function. I'm supposed to write the algorithm that compares them. I know how to write the algorithm that compares these two character arrays, thats not the issue, but what I'm failing to understand is how both X and Y get into the the overloaded function to compare them? In the main, the code ( X == Y ) is used to obtain a 0 or 1. How are X and Y passed into the function?
For instance, I would assume my function stub would need to be rewritten with 2 parameters:
int MyFloat::operator== (MyFloat x, MyFloat y)
{
int Flag=0;
return 1;
}
But doing this produces an error back in the main during the function call of ( X == Y ) that states 'Overload "operator==" must be a binary operator (has 3 parameters)'
So I'm totally confused on how to get both Objects of MyFloat into the function to compare them. I'm still fairly new to programming (5-6 months of learning), any plain and simple answers are greatly appreciated.
When you write:
if(a == b)
what it really means is:
if(a.operator==(b))
So in your method:
bool MyFloat::operator==(const MyFloat &x) const
{
// x is b in call above
// (*this) is a in call above
// Your class invariant should guarantee this:
// assert(x.NumberOfDigits < MAX_DIGITS);
// In the scope of your class' methods:
// NumberOfDigits corresponds to this->NumberOfDigits
// Number corresponds to this->Number
if(x.NumberOfDigits != NumberOfDigits) return false;
// Same as: if(x.NumberOfDigits != this->NumberOfDigits) return false;
return strncmp(x.Number, Number, NumberOfDigits) == 0;
// Same as: return strncmp(x.Number, this->Number, this->NumberOfDigits) == 0;
}
Note that I changed the signature of your method. The correct signature returns a bool and takes a const (because you don't want to change the parameter) reference (avoid copying a big object) as parameter. The method is (and must be) const because it's not supposed to modify the object and it must be callable on a const object.
Note that it is possible to define the operator as a non-member function (i.e outside of the class) with the following signature:
bool operator==(const MyFloat &a, const MyFloat &b)
You should use this pointer. For more information: Source
bool MyFloat::operator==(const MyFloat& x) const
{
for(int i = 0; i < x.MaxDigits; ++i)
{
if(x[i] != (*this)[i])
return false;
}
return true;
}
member functions (including overloaded operators) have an implicit this parameter passed in. In your case since you are using a member version of operator== you should only need one parameter the other is this.