Polymorphic operator (updated (c++) - c++

I am trying to code a formula from propositional logic in a c++ class.
A formula can be:
A variable
A negation of a formula
Two formulas joined by a connective
I could not fined a way to define these three different structures into one class so I decided to declare them as different subclasses. The problem I am having is when declaring the opperators they do not seem to override the standard ones correctly. && is returning a bool instead of a shared_ptr
Solved: just used a shared_ptr in the baseclass to itself to avoid any slicing.
#include <iostream>
#include <memory>
using namespace std;
// {0, 1, 2}
// {and, or, implies}
class formula
{
shared_ptr <formula> F;
public:
formula ()
{}
formula (shared_ptr <formula> f)
{
F = f;
}
formula (formula* f)
{
F = shared_ptr <formula> (f);
}
virtual bool evaluate ()
{
return F -> evaluate ();
}
virtual string type ()
{
return F -> type ();
}
shared_ptr <formula> address ()
{
return F;
}
virtual void assign (bool b)
{
F -> assign (b);
}
formula operator&& (formula f);
formula operator|| (formula f);
formula operator>> (formula f);
formula operator! ();
};
class variable : public formula
{
bool value;
public:
void assign (bool b)
{
value = b;
}
bool evaluate ()
{
return value;
}
string type ()
{
return "variable";
}
};
class negation : public formula
{
shared_ptr <formula> arg;
public:
negation (formula f)
{
arg = f.address ();
}
bool evaluate ()
{
return !(arg -> evaluate ());
}
string type ()
{
return "negation";
}
};
class connected : public formula
{
shared_ptr <formula> lhs, rhs;
int C;
public:
connected (formula f, formula g, int c)
{
lhs = f.address ();
rhs = g.address ();
C = c;
}
bool evaluate ()
{
if (C == 0)
return lhs -> evaluate () && rhs -> evaluate ();
else if (C == 1)
return lhs -> evaluate () || rhs -> evaluate ();
else
return !(lhs -> evaluate ()) || rhs -> evaluate ();
}
string type ()
{
return "connected";
}
};
formula formula::operator&& (formula g)
{
shared_ptr <formula> temp (new connected (*this, g, 0));
formula f (temp);
return f;
}
formula formula::operator|| (formula g)
{
shared_ptr <formula> temp (new connected (*this, g, 1));
formula f (temp);
return f;
}
formula formula::operator>> (formula g)
{
shared_ptr <formula> temp (new connected (*this, g, 2));
formula f (temp);
return f;
}
formula formula::operator! ()
{
shared_ptr <formula> temp (new negation (*this));
formula f (temp);
return f;
}
int main ()
{
formula A (new variable), B (new variable);
A.assign(true);
B.assign(false);
formula x = A&&B, y = A||B, z = A>>B, w = !B;
cout << boolalpha;
cout << x.evaluate () << endl;
cout << y.evaluate () << endl;
cout << z.evaluate () << endl;
cout << w.evaluate () << endl << endl;
B.assign(true);
cout << boolalpha;
cout << x.evaluate () << endl;
cout << y.evaluate () << endl;
cout << z.evaluate () << endl;
cout << w.evaluate () << endl;
}

You define && to accept arguments of types formula and shared_ptr<formula>. This is weirdly asymmetric and will confuse you to no end. Then you are trying to apply it to two shared_ptr<formula>s. It is not going to work.
As a stopgap measure, change
cerr << (A&&B) -> type () << endl;
to
cerr << (*A && B) -> type () << endl;
However this is unsustainable in the long run.
I would recommend split formula in two classes, formula and formula_impl, where formula_impl contains all the virtual functions of the former formula and formula contains a shared_ptr<formula_impl>. formula implements what it can (operator&& and in the future maybe other things, like operator! and operator|| and whatnot) and delegates evaluate etc. to the formula_impl pointed to by the shared pointers. The end user only sees formula, never formula_impl.
formula should also define static functions that return a variable, a negation, and a conjunction.
Some additional notes.
assign is not a very good choice for a virtual function. You can only assign a variable. It makes no sense for other types of formulas. I would get rid of this function entirely, and pass the value to the constructor of variable instead.
Base class implementations should not print "error", or do anything else. They should be pure virtual functions instead.
Magic numbers (0 is conjunction, 1 is disjunction) are not a good idea. Define a enum. Treat the default case as an error.

Related

how to overloading without arithematic operator

#include <iostream>
using namespace std;
class Expression
{
private :
double val;
public :
Expression() : val(0)
{
}
Expression(double v) : val(v)
{
}
Expression operator +(Expression a)
{
Expression a1;
a1.val = val + a.val;
return a1;
}
Expression operator --()
{
Expression temp1;
temp1.val = --val;
return temp1;
}
Expression operator --(int)
{
return Expression(val--);
}
Expression operator * (Expression b1)
{
Expression b;
b.val = val * b1.val;
return b;
}
double showvalue()
{
return val;
}
};
int main()
{
Expression E1;
Expression E2(5.5) , E3;
E3(2.0);
cout << E3.showvalue();
cout << endl;
Expression E4;
E4 = E3;
E1 = E2+--E3*E4--;
cout << E1.showvalue();
return 0;
}
In the main where I have E3(2.0)
How would I overload so it would work without doing, Expression E3(2.0);
just E3(2.0);
Our teacher says there is a way to do this, so I want to know it
Again
I want it to be only E3(2.0) or any value inside, so it works
(filling so I can post
don't read this just adding details for no reason beacasue it says so)
You might have operator() acting as assigment.
class Expression
{
public:
Expression& operator=(double d) { val = d; return *this; }
void operator()(double d) { *this = d; }
// ...
};

C++ A function that can return one of two types depending on the accepted value

fun(int a) {
if (a) return a; return "empty";
}
I need a function that gets a number and depending on which number it is returns either an int variable or a string.
Please tell me how I can implement such a function.
With C++ 17 you can use variant:
std::variant<int, std::string> fun(int a) {
if (a) return a; return "empty";
}
Or use a struct with optional:
struct r {
std::optional<int> i;
std::optional<std::string> s;
};
r fun(int a) {
r out;
if (a) out.i = a; else out.s = "empty";
return out;
}
Or for prior standards use a struct with fields indicating validity.
struct r {
enum class type {i, s};
int i;
std::string s;
type t;
};
r fun(int a) {
r out;
if (a) {
out.i = a;
out.t = r::type::i;
else {
out.s = "empty";
out.t = r::type::s;
}
return out;
}
Interpret-able languages like python does not have restrictions on type of argument and type of return value. However, C++ can only accept and return values of pre-defined type.
Now, Adding to other answers, if you don't have C++17, You could try it this way:
std::pair<int, string> func(int a)
{
if(a) return std::make_pair(a , "");
return std::make_pair(0,"string");
}
In callee, you can check for non-null against both members of std::pair.
You could accomplish this flow with exceptions! If func is expecting to work with a number that is greater than 5, for example, you could do something like:
int func(int a) {
if (a > 5) { return a; }
throw std::runtime_error("Empty");
}
int main() {
try {
int x = func(3);
// Do some stuff with x...
} catch(const std::exception &e) {
std::cout << "Looks like the num is " << e.what();
}
}
So you either process the int if things went well, or, if something bad happened, you grab the string from the exception and deal with it.
You could accomplish this by splitting the two different tasks into separate functions and continue your execution from there.
#include <iostream>
using namespace std;int inputValue = 0;
int returnInt() {
std::cout << "Returning your int" << std::endl;
return inputValue;
}
string returnString() {
std::cout << "Returning your string" << std::endl;
return "Your string";
}
int main() {
std::cout << "Please type in a number" << "\t";
std::cin >> inputValue;
if (inputValue > 5) {
returnInt();
}
else {
returnString();
}
}

A function that returns a function pointer for functions of different return types

The context of this question revolves around hard typed genetic programming.
I would like to return a function pointer from a function but these functions pointers point to functions with different return types. In another stack overflow question (Function Pointers with Different Return Types C) a return type of union was suggested however I am struggling with the implementation.
I am fairly new to C++ so please forgive my ignorance if it shows.
#include <iostream>
#include <string>
float Add(float a, float b) { return a + b; }
bool IfElse(bool a) { if (a) { return true; } else { return false; }; }
union return_type
{
float(*ffptr)(float, float);
bool(*bfptr)(bool);
};
union fptr(std::string OPERATION) {
if (OPERATION == "Add") {
return_type.ffptr = Add;
} else if (OPERATION == "IfElse") {
return_type.bfptr = IfElse;
}
return return_type;
}
int main() {
std::cout << fptr("Add") << std::endl
return 0;
}
I expect (or rather would like) this to print the address of the function Add
TL;DR version: I think you may be trying to hammer a solution into fitting a problem. Consider using something like the Visitor pattern to decouple the problem so that you don't need to know the type of the data.
A union isn't a type. It's a type of types, like a class or a struct. In order to use a return_type, you have to make an object that is a return_type. That means
union fptr(std::string OPERATION) {
if (OPERATION == "Add") {
return_type.ffptr = Add;
} else if (OPERATION == "IfElse") {
return_type.bfptr = IfElse;
}
return return_type;
}
needs to look more like
return_type fptr(std::string OPERATION) {
return_type result; // make a return_type object
if (OPERATION == "Add") {
result.ffptr = Add; // set a member of the object
} else if (OPERATION == "IfElse") {
result.bfptr = IfElse;
}
return result; // return the object
}
Then you can
int main() {
std::cout << fptr("Add").ffptr(10,20) << std::endl; // call the stored function
return 0;
}
The big problem with unions is knowing what is in them. You can only safely use ffptr if ffptr was the last member set.
int main() {
std::cout << fptr("Add").bfptr(true) << std::endl;
return 0;
}
will compile, but will not behave well at all when run. What will happen is undefined, but odds are good that it won't be pretty.
You have to be absolutely certain that the function stored in the union is the correct one. If your compiler is up to date, you can use std::variant to help out here. It will at least tell you you're headed in the wrong direction by throwing an exception
#include <iostream>
#include <string>
#include <variant>
float Add(float a, float b) { return a + b; }
bool IfElse(bool a) { if (a) { return true; } else { return false; }; }
using return_type = std::variant<float (*)(float a, float b), bool (*)(bool a)>;
return_type fptr(std::string OPERATION) {
return_type result;
if (OPERATION == "Add") {
result = Add;
} else if (OPERATION == "IfElse") {
result = IfElse;
}
return result;
}
int main() {
std::cout << std::get<float (*)(float a, float b)>(fptr("Add"))(10,20) << std::endl;
try
{
std::cout << std::get<bool (*)(bool a)>(fptr("Add"))(true) << std::endl;
}
catch (const std::bad_variant_access& e)
{
std::cout << e.what() << std::endl;
}
return 0;
}
But at the end of the day it's still not all that useful. I think you may find the Visitor pattern or one of its friends more helpful.
You were close.
Be careful not to conflate the declaration of the (union) type name and the function return value. Since you want to reference pointer address, I added a void* to your union (fpaddr), so you can clearly identify that you are printing an address. Note that your fptr("Add") returned the union, and you needed to disambiguate which interpretation of the union you wanted.
#include <iostream>
#include <string>
float Add(float a, float b) { return a + b; }
bool IfElse(bool a) { if (a) { return true; } else { return false; }; }
//typedef //in C you would use 'typedef'
union fp_return_t
{
float(* ffptr )(float, float);
bool(* bfptr )(bool);
void* fpaddr;
}; //fp_return_t; //in C you would give the name here
fp_return_t fptr(std::string OPERATION) {
fp_return_t fp_return;
if (OPERATION == "Add") {
std::cout << "Add:" << (void*) Add << std::endl;
fp_return.ffptr = Add;
} else if (OPERATION == "IfElse") {
std::cout << "IfElse:" << (void*) IfElse << std::endl;
fp_return.bfptr = IfElse;
}
return fp_return;
}
int main() {
std::cout << fptr("Add").fpaddr << std::endl;
return 0;
}
I'm not quite sure what the ultimate goal is but here's how you can make the above compile and print the function address (printing of a plain Add added for comparison):
#include <iostream>
#include <string>
float Add(float a, float b) { return a + b; }
bool IfElse(bool a) { return a; }
union return_type
{
float(*ffptr)(float, float);
bool(*bfptr)(bool);
};
union return_type fptr(std::string OPERATION) {
union return_type r;
if (OPERATION == "Add") {
r.ffptr = Add;
} else if (OPERATION == "IfElse") {
r.bfptr = IfElse;
}
return r;
}
int main()
{
/*the void*-cast is technically nonportable but it's hard to
print fn-pointers portably*/
std::cout << reinterpret_cast<void*>(Add) << '\n';
/*you should know which union member is active: */
std::cout << reinterpret_cast<void*>(fptr("Add").ffptr) << '\n';
/*^should be the same address*/
return 0;
}

Why does my condition not work?

I have the following code:
#include <iostream>
using namespace std;
int a, b, sqr;
const int P = 3.14; //Later for circles...
string s1;
class MathsFunctions{
public:
virtual void square(int a, int b)=0;
};
class TriangleFunc: public MathsFunctions{
public:
void square(int a, int b){
sqr = (a * b)/2;
cout << "Square of triangle is: "<< sqr << endl;
}
};
class RectangleFunc: public MathsFunctions{
public:
void square(int a, int b){
sqr = a * b;
cout << "Square of rectangle is: "<< sqr << endl;
}
};
void getNumbers(){
cout << "Enter the first number: "<<endl;
cin >> a;
cout << "Enter the second number: "<< endl;
cin >> b;
}
void chooseTheFigure(){
cout << "Choose the figure (rectangle or triangle): "<< endl;
cin >> s1;
}
int main(){
chooseTheFigure();
getNumbers();
if(s1 == "rectangle" || "Rectangle"){
RectangleFunc r;
MathsFunctions * m = &r;
m -> square(a,b);
};
if (s1 == "triangle" || "Triangle"){
TriangleFunc t;
MathsFunctions *m = &t;
m -> square(a,b);
};
}
I created a program which is count the square of rectangle or triangle. There is a condition in main() but in the end program shows both results. How can I improve that?
Screenshot of output of the program:
This doesn't do what you think it does:
if(s1 == "rectangle" || "Rectangle"){
RectangleFunc r;
MathsFunctions * m = &r;
m -> square(a,b);
};
The if-expression above is evaluated as:
if((s1 == "rectangle") || ("Rectangle"))
// ^^^^^^^^^^^^^^^^^ or ^^^^^^^^^^
Now, the second part there, "Rectangle" is a string-literal which implicitly converts to a valid pointer. And any pointer other than nullptr or some zero like integer evaluates to true - always.
You probably meant to write:
if((s1 == "rectangle") || (s1 == "Rectangle")){
RectangleFunc r;
MathsFunctions * m = &r;
m -> square(a,b);
};
----------------------------------------
There are a few other nuances in your code, such
not having a vitual destructor in your base class and,
this:
const int P = 3.14; //Later for circles...
P will not hold the value you expect.
if(s1 == "rectangle" || "Rectangle"){
There are 2 conditions when this is true, the first is what you expect, the second is your bug because it's now what you meant to say in your code:
1) the input string s1, compared for equality to the string literal "rectangle" returns true, or
2) if the string-literal "Rectangle", by itself, is considered a true value.
As this conversion is essentially a "null pointer check", and the string literal is never null, this case is always true.
What you need is to repeat the test:
if(s1 == "rectangle" || s1 == "Rectangle"){
1.As WhiZtim pointed out, Or operator needs correction
if(s1 == "rectangle" || "Rectangle") {...}
will always be true as "Rectangle" is not null.
You should use string compare functions for strings (see strcmpi())
Edit
Regarding string functions, check this out:
Case-insensitive string comparison in C++

Is this code legal in ISO C++?

So I'm trying to implement function parameters which can be uninitialized. Here is the code which I have written. My question is if it's legal by the ISO C++ standard (version 14 if possible).
#include <iostream>
#include <typeinfo>
using namespace std;
template<typename type>
struct nzeroinittmpliteral
{
nzeroinittmpliteral() { }
nzeroinittmpliteral(type arg) { d = arg; }
//nzeroinittmpliteral(const nzeroinittmpliteral &) = delete;
operator type () & { return d; }
operator type () && { return d; }
type d;
} ;
void func(bool bIsPointerValid, nzeroinittmpliteral<int *> pVar = {})
{
if(bIsPointerValid)
{
cout << *pVar << endl;
}
else
{
pVar = new int;
*pVar = 8;
cout << *pVar << endl;
delete pVar;
}
}
int main()
{
func(true, { (int *)&(const int &)int{9} } );
func(false);
}
If you want to pass a parameter that may be uninitialized, simply don't pass it, use overloading. Look:
void func(int value)
{
cout << value << endl;
}
void func()
{
// no 'value' was initialized here :)
func(8);
}
Or simply give a default value to the parameter if you will provide one anyway in your body:
void func(int value = 8)
{
cout << value << endl;
}
Besides that, you can take a look at boost::optional:
void func(boost::optional<int> optvalue = boost::none) {
if (optvalue) {
cout << *optvalue << endl;
} else {
// nothing passed
cout << "foo" << endl;
}
}
Directly answering your question: your code is valid.
func(true, { (int *)&(const int &)int{9} } );
By casting the temporary to a const reference, you extend its lifetime to the lifetime of the reference itself, which ends after func returns. But this is too redundant, you could simply have written:
void func(int* value) { if (value) {...} }
func(&(const int &)9);
func(nullptr);
The actual parameter being passed is your nzeroinittmpliteral and it is initialized by calling one of the constructors, always. The default constructor doesn't initialize the d member, but this is no big improvement as it is just a pointer. Using nullptr is better and removes the need for the bool parameter.