Error C2451 using boost::any - c++

class A {
public:
void f()
{
cout << "A()" << endl;
}
};
class B {
public:
void f()
{
cout << "B()" << endl;
}
};
class C {
public:
void f()
{
cout << "C()" << endl;
}
};
void print(boost::any& a)
{
if(A* pA = boost::any_cast<A>(&a))
{
pA->f();
}
else if(B* pB = boost::any_cast<B>(&a))
{
pB->f();
}
else if(C* pC = boost::any_cast<C>(&a))
{
pC->f();
}
else if(string s = boost::any_cast<string>(a))
{
cout << s << endl;
}
else if(int i = boost::any_cast<int>(a))
{
cout << i << endl;
}
}
int main()
{
vector<boost::any> v;
v.push_back(A());
v.push_back(B());
v.push_back(C());
v.push_back(string("Hello boy"));
v.push_back(24);
for_each(v.begin(), v.end(), print);
}
I'm getting this error in print() when testing for string using Visual Studio 2010:
error C2451: conditional expression of type 'std::string' is illegal
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

else if(string s = boost::any_cast<string>(a))
This line is causing you problems. string s is not a pointer, it's a stack variable. You can't do a check for null.
The reason you can do a check on the integer below is that integers implicitly map to bool.
0 -> FALSE
1 -> TRUE

You shouldn't use any_cast on a reference here, because it throws a bad_any_cast exception if the type isn't right. Use a pointer in the last two cases like you did with the first three:
else if(string* s = boost::any_cast<string*>(&a))
{
cout << *s << endl;
}
else if(int* i = boost::any_cast<int*>(&a))
{
cout << *i << endl;
}

Related

Implementation of constructor for size in stack using array in c++

#include <iostream>
using namespace std;
class Stack {
private:
int size;
public:
Stack(int n)
{
size = n;
}
int stack_arr[size], top = -1;
void push(int a)
{
if (top >= 4)
cout << "Stack is full" << endl;
else {
top++;
stack_arr[top] = a;
}
}
void pop()
{
if (top <= -1)
cout << "There is no element remaining in stack" << endl;
else {
cout << "The popped element is " << stack_arr[top] << endl;
top--;
}
}
void peek()
{
if (top < 0) {
cout << "Stack is Empty";
}
else {
int x = stack_arr[top];
cout << "The last element in the Stack is: ";
cout << x << endl;
}
}
int isempty()
{
if (top == -1)
cout << "Stack is Empty: ";
else
return false;
}
void display()
{
if (top >= 0) {
cout << "Stack elements are:";
for (int i = top; i >= 0; i--)
cout << stack_arr[i] << " ";
cout << endl;
}
else
cout << "Stack is empty";
}
};
int main()
{
Stack s(5);
s.push(10);
s.push(12);
s.push(14);
s.push(10);
s.push(12);
s.push(14);
s.peek();
s.display();
s.pop();
s.display();
}
I'm facing the issue while compilation
13:9: error: invalid use of non-static data member 'Stack::size'
14:15: error: from this location
In member function 'void Stack::push(int)':
21:7: error: 'stack_arr' was not declared in this scope
In member function 'void Stack::pop()':
28:40: error: 'stack_arr' was not declared in this scope
In member function 'void Stack::peek()':
38:17: error: 'stack_arr' was not declared in this scope
In member function 'void Stack::display()':
53:13: error: 'stack_arr' was not declared in this scope
can anyone help me for giving idea how i can get stack size from constructor,if im doing wrong approach
I made your code compile, you had to do two simple modifications:
private:
int size;
int* stack_arr;
int top = 0;
public:
Stack(int n)
{
size = n;
stack_arr = new int[size];
}
You forgot to define top, also to achieve what you tried with a dynamic array you can use new. I also fixed some issues that lead to random dygits while printing, you basically were going out of array scope:
void push(int a) {
if (top == size - 1) // in your code it was top<=4,
//suppose it was only for your specific test case
// your forgot that it has to be generic
cout << "Stack is full" << endl;
else {
top++;
stack_arr[top] = a;
}
}
void pop() {
if (top == -1)
cout << "There is no element remaining in stack" << endl;
else {
cout << "The popped element is " << stack_arr[top] << endl;
top--;
}
}
void peek()
{
if (top == -1) {
cout << "Stack is Empty";
}
else {
int x = stack_arr[top];
cout << "The last element in the Stack is: ";
cout << x << endl;
}
}
int isempty() {
if (top == -1)
cout << "Stack is Empty: ";
else
return false;
}
void display() {
if (top > -1) {
cout << "Stack elements are:";
for (int i = top; i >= 0; i--)
cout << stack_arr[i] << " ";
cout << endl;
}
else
cout << "Stack is empty";
}
In modern c++ there is a rule: If you have anything in your class using new, you should make a destructor. And if you create a destructor, you should create copy constructor, and copy assignment operator (Its called rule of 3). For bonus, in this case, at least in my opinion, I also created move constructor and move assignment operator ( likely you wont use then in your case, that's why I say its bonus. It's known as rule of 5).
//Destructor
~Stack()
{
delete [] stack_arr;
}
//copy Constructor
Stack(const Stack& s)
:
size(s.size),
stack_arr(new int[size]),
top(s.top)
{
for (int i = 0; i <= top; i++) stack_arr[i] = static_cast<int>(s.stack_arr[i]);
}
//copy assignment operator
Stack& operator=(const Stack& s)
{
if (stack_arr != nullptr) delete[] stack_arr;
size = s.size;
top = s.top;
stack_arr = new int[size];
for (int i = 0; i <= top; i++) stack_arr[i] = static_cast<int>(s.stack_arr[i]);
return *this;
}
//move constructor
Stack(Stack&& s) noexcept :
top(std::move(s.top)),
size(std::move(s.size)),
stack_arr(std::move(s.stack_arr))
{
s.stack_arr = nullptr;
}
//move assignment operator
Stack& operator=(Stack&& s)noexcept
{
if (this != &s)
{
if (stack_arr != nullptr) delete[] stack_arr;
size = std::move(s.size);
top = std::move(s.top);
stack_arr = std::move(s.stack_arr);
}
return *this;
}
You can do what std::stack does, and delegate to an existing container type.
#include <iostream>
#include <vector>
class Stack {
private:
std::vector<int> data;
public:
Stack(std::size_t n) : data(n)
{
}
void push(int a)
{
try {
data.push_back(a);
} catch (std::bad_alloc) {
std::cout << "stack is full" << std::endl;
}
}
void pop()
{
if (data.empty()) {
std::cout << "There is no element remaining in stack" << std::endl;
} else {
std::cout << "The popped element is " << data.back() << std::endl;
data.pop_back();
}
}
void peek()
{
if (data.empty()) {
std::cout << "Stack is Empty" << std::endl;
} else {
std::cout << "The last element in the Stack is: " << data.back() << std::endl;
}
}
bool isempty()
{
return data.empty();
}
void display()
{
if (!data.empty()) {
std::cout << "Stack elements are:";
for (int i : data) {
std::cout << i << " ";
}
std::cout << endl;
} else {
std::cout << "Stack is empty" << endl;
}
}
};

Does std::any_cast call destructor? How the cast works?

#include <iostream>
#include <any>
using namespace std;
class c {
public:
c() :a{ 0 } { cout << "constructor\n"; }
c(int aa) :a{ aa } { cout << "Constructor\n"; }
~c() { cout << "destructor\n"; }
int get() { return a; }
private:
int a;
};
auto main()->int
{
any a{ 5 };
cout << any_cast<int>(a) << '\n';
a.emplace<c>(3);
cout << '!' << any_cast<c>(a).get() << '\n';
//des
cout << '\n';
a.emplace<c>(9);
cout << '!' << any_cast<c>(a).get() << '\n';
//des
}
destructor called after each any_cast.
and, below code makes run-time error.
I think the cause is any_cast(C)'s work pipeline is might be like
~C() then X(C) ERROR!!C doesn't exist
any_cast really work like that?
I add blow codes and make run-time error.
class X {
public:
X() :a{ 0 } { cout << "xonstructor\n"; }
X(c& aa) :a{ aa.get() } { cout << "Xonstructor\n"; }
~X() { cout << "Xdestructor\n"; }
int get() { return a; }
private:
int a;
};
auto main()->int
{
any a{ 5 };
cout << any_cast<int>(a) << '\n';
a.emplace<c>(3);
cout << '!' << any_cast<X>(a).get() << '\n';
//runtime error after '!'
cout << '\n';
a.emplace<c>(9);
cout << '!' << any_cast<X>(a).get() << '\n';
}
You are copying a c (or X) from the one within the std::any. That copy is destroyed at the end of the expression, after having been streamed out.
any_cast does not do any conversion. It throws if you ask it for a type different to the one it stores. When you have emplaced a c and asked for an X, it throws std::bad_any_cast, because X is not c.

Is passing an r-value to functions returning it considered wrong in C++?

I want to create a function Service that energize an exhausted phone and return it as follows.
Writing
Phone p;
p = Service(p);
does not look elegant so I want to write as follows.
Phone& p = Service(Phone());
Doing so produces weird outputs as follows.
Ctor
Dtor
Destroyed
Energy: 100%
Ending...
The expected output is:
Ctor
Energy: 100%
Dtor
Destroyed
Ending...
Question
Could you tell me why this happens?
Note: I am new to C++.
class Phone
{
private:
int energy;
bool destroyed = false;
public:
Phone() : energy{ 0 } {
cout << "Ctor" << endl;
}
~Phone()
{
cout << "Dtor" << endl;
if (destroyed == false)
{
cout << "Destroyed..." << endl;
destroyed = true;
}
}
void Energize() { energy = 100; }
void Status() const
{
cout << "Energy: " << energy << "%" << endl;
}
};
Phone& Service(Phone&& input)
{
input.Energize();
return input;
}
int main()
{
Phone& p = Service(Phone());
p.Status();
cout << "Ending..." << endl;
}
It makes no sense to return a copy of the phone. So just pass it as reference and operate on it:
void Service(Phone& phone);
Phone p{};
Service(p);

abnormal behaviour while displaying char array in C++ after object initialization

main():
char inp[] = "(A+B)/(C*D))";
Infix i;
cout << "In main: " << inp /* + ')' */ << endl << endl;
Here is Infix constructor:
Infix() {
push('(');
cout << "Element In Stack: " << *returnElement(returnTop()) << endl;
outputString = "";
strcpy(operatorArray, "/*-+%");
cout << "Operator Array: " << operatorArray << endl;
}
Infix is inheriting from a class 'Stack':
class Stack{
int top = -1;
char arr[100];
public:
bool push(char);
char pop();
char peek();
bool isEmpty();
void displayAll();
char returnTop() { return top;}
char* returnElement(int i) {
if(i > 98){
cout << "StackOutOfIndex";
return nullptr;
}
return &arr[i];
}
};
When I run the code in main, it displays unusual output:
Element In Stack: (
Operator Array: /*-+%
In main: +%
Stack Object Destroyed!
But, when in main, if the comment the line declaring 'Infix' object declaration, the code runs fine:
In main: (A+B)/(C*D))
EDITS:
Stack Class
#include<iostream>
using namespace std;
class Stack{
int top = -1;
char arr[100];
public:
bool push(char);
char pop();
char peek();
bool isEmpty();
void displayAll();
char returnTop() { return top;}
char* returnElement(int i) {
if(i > 98){
cout << "StackOutOfIndex";
return nullptr;
}
return &arr[i];
}
};
bool Stack:: push(char elementToPush) {
if(top > 98) {
cout << "\nStack Overflow!!";
return false;
} else {
arr[++top] = elementToPush;
return true;
}
}
char Stack:: pop() {
if(top <= -1) {
cout << "\nStack Underflow!!";
return ' ';
} else {
return (arr[top--]);
}
}
char Stack:: peek() {
if(top > 98) {
cout << "\nStack Overflow!!";
return ' ';
} else {
return arr[top];
}
}
bool Stack:: isEmpty() {
return (top <= 0);
}
void Stack:: displayAll() {
if(top <= -1) {
cout << "null";
return;
}
int i = top;
while (i >= 0) {
cout << arr[i] << " ";
--i;
}
cout << "\n";
}
Infix Class
#include<iostream>
#include<cstring>
#include<D:\Programs\11Stack.cpp>
using namespace std;
class Infix : public Stack {
string outputString;
char operatorArray[];
public:
Infix() {
push('(');
cout << "Element In Stack: " << *returnElement(returnTop()) << endl;
outputString = "";
strcpy(operatorArray, "/*-+%");
cout << "Operator Array: " << operatorArray << endl;
}
string infixToPostfix(char *, int);
bool manupulateOperator(char, int);
int checkPrecedence(char);
~Infix() {
cout << "\nStack Object Destroyed!" << endl;
}
};
string Infix:: infixToPostfix(char *str, int size) {
cout << "\nGiven String: " << str << endl;
int x;
for(int i = 0; i < size; ++size) {
x = str[i];
if(x != ' ') {
if(x == ')') {
while(returnTop() != '(') {
cout << pop() << " popped!\n";
}
cout << pop() << " popped!\n";
} else if(isalpha(x)) {
cout << x;
} /* else{ // scanned character is an operator
if(manupulateOperator(x, i)) {
} else {
return " ";
}
} */
}
}
return outputString;
}
bool Infix::manupulateOperator(char c, int position) {
try {
char topElement = *returnElement(returnTop());
if(checkPrecedence(c) == -1) {
cout << "\nErr\n";
}else if((checkPrecedence(c) > checkPrecedence(topElement)) || returnTop() == 0) {
push(c);
cout << c << " pushed!\n";
}
} catch(std::exception e) {
std::cerr << e.what() << '\n';
return false;
} catch (char* Ce) {
cout << Ce << endl;
}
return true;
}
int Infix::checkPrecedence(char c) {
/*
+ -> 1
- -> 1
* -> 2
/ -> 2
% -> 2
*/
switch(c) {
case '+':
return 1;
case '-':
return 1;
case '*':
return 2;
case '/':
return 2;
case '%':
return 2;
default:
// throw "Illegal Operator Detected!";
cout << "Illegal Operator Detected: " << c << endl;
return -1;
}
}
int main() {
cout << endl;
int x = 1;
char inp[] = "(A+B)/(C*D))";
//Infix i;
cout << "In main: " << inp /* + ')' */ << endl << endl;
// cout << i.infixToPostfix(input + ')', sizeof(input));
/* for(int i = 0; i < strlen(inp); ++i) {
cout << inp[i];
}
*/
return 0;
}
You are declaring operatorArray as an array of char but you are not assigning any memory for it! So, when you then call strcpy(operatorArray, "/*-+%"); in your Infix constructor, you are causing undefined behaviour by attempting to copy the given string constant to memory that hasn't been assigned - and this appears to be overwriting the inp[] array declared in your main.
To fix this, I would suggest giving your operatorArray member a specific size, which will be large enough to accommodate whatever string you want to copy to it - 8 characters will work in the sample code you've given:
class Infix : public Stack {
string outputString;
char operatorArray[8]; // Make this member a REAL array of characters.
//..
Your variable char operatorArray[] have no memory allocated when your constructor is called. When you use strcpy, you write to a place where you don't have permissions in your memory, and therefore on other informations.
To find these kinds of mistakes, I recommend using valgrind.
char operatorArray[]; is not allowed in Standard C++.
If you didn't see an error message then I would recommend adjusting compiler settings to follow the standard form of the language, this would have saved you a lot of time.

Why does overloading the post increment operator in C++ call the constructor twice?

I was playing with overloading different operators and added print statements to watch what was happening. When I overloaded the post increment operator, I saw that the constructor was being called twice, but I don't understand why.
#include <iostream>
using namespace std;
class ParentClass {
public:
ParentClass() {
cout << "In ParentClass!" << endl;
}
};
class ChildClass : public ParentClass {
public:
int value;
ChildClass() { }
ChildClass(int a)
: value(a) {
cout << "In ChildClass!" << endl;
}
int getValue() { return value; }
ChildClass operator++( int ) {
cout << "DEBUG 30\n";
this->value++;
return this->value;
}
};
int main() {
cout << "DEBUG 10\n";
ChildClass child(0);
cout << "value initial = " << child.getValue() << endl;
cout << "DEBUG 20\n";
child++;
cout << "DEBUG 40\n";
cout << "value incremented = " << child.getValue() << endl;
}
The output after running this code is:
DEBUG 10
In ParentClass!
In ChildClass!
value initial = 0
DEBUG 20
DEBUG 30
In ParentClass!
In ChildClass!
DEBUG 40
value incremented = 1
This statement
return this->value;
Says return int
But the method prototype is
ChildClass operator++( int )
So the compiler thinks, got an int need a ChildClass - Lets construct one from the int. Hence the output