failed attempt of using boost::optional - c++

I have been trying to use boost optional for a function that could either return an object or a null and I cant figure it out. Here is what I have so far. Any suggestions on how to resolve this issue would be appreciated.
class Myclass
{
public:
int a;
};
boost::optional<Myclass> func(int a) //This could either return MyClass or a null
{
boost::optional<Myclass> value;
if(a==0)
{
//return an object
boost::optional<Myclass> value;
value->a = 200;
}
else
{
return NULL;
}
return value;
}
int main(int argc, char **argv)
{
boost::optional<Myclass> v = func(0);
//How do I check if its a NULL or an object
return 0;
}
Update:
This is my new code and I am getting a compiler error at value = {200};
class Myclass
{
public:
int a;
};
boost::optional<Myclass> func(int a)
{
boost::optional<Myclass> value;
if(a == 0)
value = {200};
return value;
}
int main(int argc, char **argv)
{
boost::optional<Myclass> v = func(0);
if(v)
std::cout << v -> a << std::endl;
else
std::cout << "Uninitilized" << std::endl;
std::cin.get();
return 0;
}

Your function should look like following:
boost::optional<Myclass> func(int a)
{
boost::optional<Myclass> value;
if(a == 0)
value = {200};
return value;
}
And you could check it by casting to bool:
boost::optional<Myclass> v = func(42);
if(v)
std::cout << v -> a << std::endl;
else
std::cout << "Uninitilized" << std::endl;
Isnt it going to be value->a = 200
No, it isn't. From Boost.Optional.Docs:
T const* optional<T (not a ref)>::operator ->() const ;
T* optional<T (not a ref)>::operator ->() ;
Requirements: *this is initialized.
Returns: A pointer to the contained value.
Throws: Nothing.
Notes: The requirement is asserted via BOOST_ASSERT().
And in the operator-> definition:
pointer_const_type operator->() const
{
BOOST_ASSERT(this->is_initialized());
return this->get_ptr_impl();
}
If object is not initialized, assertion will be failed. When we write
value = {200};
We initialize value with Myclass{200}.
Note, that value = {200} requires support for initializer lists(C++11 feature). If your compiler doesn't support it, you could use it like this:
Myclass c;
c.a = 200;
value = c;
Or provide constructor for Myclass with int as argument:
Myclass(int a_): a(a_)
{
}
Then you could just write
value = 200;

Related

C structure object member name as parameter

How can I pass a structure name, object name, different member name(whose value to be verified) as a parameter to a function ?
struct st{
int a;
int b;
}
bool verify(____ st , ____ b){
if(obj.b == 5)return true;
return false;
}
int main(){
st obj;
// now that I know all the names of members of struct name
// HOW can I verify passing different member name as parameter
cout<<verify(__,__);
}
For an instance:
(example with error)
#include<iostream>
using namespace std;
struct st{
int a;
int b;
};
bool verify(st obj, st.a val){
if(obj.a==val)
return true;
}
int main()
{
cout<<"Hello World"<<endl;
st obj;
cout<<verify(obj,a);
//cout<<verify(obj,b);
return 0;
}
You can use a pointer to data member:
bool verify(const st &obj, int st::* field) {
return obj.*field == 5;
}
...
st obj;
std::cout << verify(obj, &st::a);
std::cout << verify(obj, &st::b);
But the syntax is confusing and just passing a reference to the data member to verify is easier:
bool verify(int field) {
return field == 5;
}
...
st obj;
std::cout << verify(obj.a);
std::cout << verify(obj.b);
Using a template:
#include <iostream>
struct st
{
int a;
int b;
};
struct st2
{
int c;
int d;
};
template<typename T>
bool verify(const T &obj, int T::* field)
{
return obj.*field == 5;
}
int main()
{
st obj = {5, 6};
st2 obj2 = {5, 6};
std::cout << verify(obj, &st::a) << "\n"; // 1, since obj.a is 5
std::cout << verify(obj2, &st2::d) << "\n"; // 0, since obj.d is not 5
return 0;
}

Multiple functions for a class does not store previous results

Problem
I want to create a function inside a class which function2 will use the result generated from function1. I have a small code snippet where I tried to make it easy to understand.
#include <stdio.h>
class GreaterSmaller {
public:
int greater, smaller;
};
GreaterSmaller findGreaterSmaller(int a, int b)
{
GreaterSmaller s;
if (a > b) {
s.greater = a;
s.smaller = b;
}
else {
s.greater = b;
s.smaller = a;
}
return s;
}
GreaterSmaller print()
{
GreaterSmaller s;
std::cout << s.greater << s.smaller << std::endl;
}
int main()
{
int x = 4;
int y = 3;
GreaterSmaller result;
result = findGreaterSmaller(x, y);
result = print(); // I want it to print 4 & 3
return 0;
}
P.s Just wanted to mention I am not trying to print the result in the function2 I have created that for a demo.
Define the second method as taking an argument of the first type, and pass it when you call it, as such:
void print(GreaterSmaller &s)
{
std::cout << s.greater << s.smaller << std::endl;
}
print(result); // I want it to print 4 & 3

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();
}
}

c++ Copy constructors and destructors

I am learning constructors and Destructors in c++; Help me grasp my mistakes even if they are silly...
HERE is a code I have written to perform addition using classes in c++; This creates two summands of datatype num and employs the constructor sum() to perform sum of the two numbers; However when everything was goin' alright, I stumbled upon creating a copy constructor for num , (Although not necessary but still for practice)... without the dynamic object of the class sum it is not possible to run the code anyway(without removing the copy constructor)... Help me improve my code and my mistakes in the code below; Also I wanna know how to make use of the copy constructor in this program; the problem being that in the destructor the delete operation is being performed multiple times on the same piece of memory (I suppose)
Here's my Code
#include<iostream>
#include<new>
using namespace std;
class num
{
public:
int *a;
num(int x)
{
try
{
a=new int;
}
catch(bad_alloc xa)
{
cout<<"1";
exit(1);
}
*a=x;
}
num(){ }
num(const num &ob)
{
try
{
a=new int;
}
catch(bad_alloc xa)
{
cout<<"1''";
exit(2);
}
*a=*(ob.a);
}
~num()
{
cout<<"Destruct!!!";
delete a;
}
};
class sum:public num
{
public:
int add;
sum(num n1,num n2)
{
add=*(n1.a)+*(n2.a);
}
int getsum()
{
return add;
}
};
int main()
{
num x=58;
num y=82;
sum *s=new sum(x,y);
cout<<s->getsum();
delete s;
return 0;
}
I may miss something - didn't use new/delete for too long, but tried to correct all what I noticed.
P.S. always use smart pointers.
#include <iostream>
#include <exception>
#include <new>
using namespace std;
int* allocate(const char* err_msg, int exit_code)
{
int* a = nullptr;
try
{
a = new int;
}
catch (bad_alloc&)
{
cout << err_msg << endl;
exit(exit_code);
}
return a;
}
class num
{
int* a = nullptr; // always should be initialized here
public:
num() noexcept : a(nullptr) // or here
{}
/*explicit*/ num(int x) : a(allocate("1", 1))
{
*a = x;
}
num(const num& ob) : a(allocate("1''", 2))
{
*a = *(ob.a);
}
// rule of zero/three/five
// default copy assignment will copy pointer and one int will be leaked and one will be deleted twice
num& operator =(const num& ob)
{
if (&ob == this)
{
return *this;
}
*a = *(ob.a);
return *this;
}
~num()
{
cout << "Destruct!!!";
delete a;
a = nullptr; // usefull for debug
}
int value() const
{
if (a == nullptr)
{
throw runtime_error("a == nullptr");
}
return *a;
}
};
class sum
{
int add = 0;
public:
sum(const num& n1, const num& n2)
{
add = n1.value() + n2.value();
}
int getsum() const
{
return add;
}
};
int main()
{
const num x = 58;
const num y = 82;
const sum* s = new sum(x, y);
cout << s->getsum() << endl;
delete s;
return 0;
}

C++ function pointer (class member) to non-static member function

class Foo {
public:
Foo() { do_something = &Foo::func_x; }
int (Foo::*do_something)(int); // function pointer to class member function
void setFunc(bool e) { do_something = e ? &Foo::func_x : &Foo::func_y; }
private:
int func_x(int m) { return m *= 5; }
int func_y(int n) { return n *= 6; }
};
int
main()
{
Foo f;
f.setFunc(false);
return (f.*do_something)(5); // <- Not ok. Compile error.
}
How can I get this to work?
class A{
public:
typedef int (A::*method)();
method p;
A(){
p = &A::foo;
(this->*p)(); // <- trick 1, inner call
}
int foo(){
printf("foo\n");
return 0;
}
};
void main()
{
A a;
(a.*a.p)(); // <- trick 2, outer call
}
The line you want is
return (f.*f.do_something)(5);
(That compiles -- I've tried it)
"*f.do_something" refers to the pointer itself --- "f" tells us where to get the do_something value from. But we still need to give an object that will be the this pointer when we call the function. That's why we need the "f." prefix.
class A {
int var;
int var2;
public:
void setVar(int v);
int getVar();
void setVar2(int v);
int getVar2();
typedef int (A::*_fVar)();
_fVar fvar;
void setFvar(_fVar afvar) { fvar = afvar; }
void insideCall() { (this->*fvar)(); }
};
void A::setVar(int v)
{
var = v;
}
int A::getVar()
{
std::cout << "A::getVar() is called. var = " << var << std::endl;
return var;
}
void A::setVar2(int v2)
{
var2 = v2;
}
int A::getVar2()
{
std::cout << "A::getVar2() is called. var2 = " << var2 << std::endl;
return var2;
}
int main()
{
A a;
a.setVar(3);
a.setVar2(5);
// a.fvar = &A::getVar;
a.setFvar(&A::getVar);
(a.*a.fvar)();
a.setFvar(&A::getVar2);
(a.*a.fvar)();
a.setFvar(&A::getVar);
a.insideCall();
a.setFvar(&A::getVar2);
a.insideCall();
return 0;
}
I extended Nick Dandoulakis's answer. Thank you.
I added a function which set the member function pointer from outside of the class. I added another function which can be called from outside to show inner call of member function pointer.
Try (f.*do_something)(5);
#include<iostream>
using namespace std;
class A {
public:
void hello()
{
cout << "hello" << endl;
};
int x = 0;
};
void main(void)
{
//pointer
A * a = new A;
void(A::*pfun)() = &A::hello;
int A::*v1 = &A::x;
(a->*pfun)();
a->*v1 = 100;
cout << a->*v1 << endl << endl;
//-----------------------------
A b;
void(A::*fun)() = &A::hello;
int A::*v2 = &A::x;
(b.*fun)();
b.*v2 = 200;
cout << b.*v2 << endl;
}
I think calling a non static member of the class could also be done using a static member function.