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;
}
Related
Is it possible to have an array with int values and int references?
Is there any other way to have an array arr such that when you print arr[1] it always prints the value of arr[0] (without having to update arr[1] when arr[0] is modified) ?
No, but you may have such a desired array:
#include <iostream>
using namespace std;
class CIntRef
{
public:
CIntRef(const int & ref) : ref(ref) {}
operator const int &() { return ref; }
const int& operator=(const int &i) {
const_cast<int&>(ref) = i;
return ref;
}
private:
const int & ref;
};
int main()
{
int a = 2;
CIntRef arr[] = { a, a, 0, 1 };
cout << arr[1] << endl; // <-- prints: 2
arr[0] = 3;
cout << arr[1] << endl; // <-- prints: 3
return 0;
}
So I have a header file:
struct inner1 {
int w;
int x;
};
struct inner2 {
int y;
int z;
};
struct outer{
inner1 *a;
inner2 *b;
};
Now in main, I want to initialize these structures and use them. How do I initialize all three structures so that outer recognizes inner1 and inner2 as the specific structs it points to. Then lets say I want to access the variable w. Is it outer.a->w? I am unfamiliar with nested structures dealing with pointers. Any help is appreciated.
struct inner1 {
int w;
int x;
};
struct inner2 {
int y;
int z;
};
struct outer{
inner1 *a;
inner2 *b;
};
int _tmain(int argc, _TCHAR* argv[])
{
outer o;
o.a = new inner1();
o.b = new inner2();
o.a->w = 1;
o.a->x = 2;
o.b->y = 3;
o.b->z = 4;
//do stuff
delete o.a;
delete o.b;
return 0;
}
This will permit you to declare and initialize the structures.
Here is a demonstrative program
#include <iostream>
int main()
{
struct inner1 {
int w;
int x;
};
struct inner2 {
int y;
int z;
};
struct outer{
inner1 *a;
inner2 *b;
};
outer o = { new inner1 { 10, 20 }, new inner2 { 30, 40 } };
std::cout << "o.a->w = " << o.a->w << ", o.a->x = " << o.a->x
<< ", o.b->y = " << o.b->y << ", o.b->z = " << o.b->z
<< std::endl;
delete o.a;
delete o.b;
}
The program output is
o.a->w = 10, o.a->x = 20, o.b->y = 30, o.b->z = 40
Or you could do the following way
#include <iostream>
int main()
{
struct inner1 {
int w;
int x;
};
struct inner2 {
int y;
int z;
};
struct outer{
inner1 *a;
inner2 *b;
};
inner1 i1 = { 10, 20 };
inner2 i2 = { 30, 40 };
outer o = { &i1, &i2 };
std::cout << "o.a->w = " << o.a->w << ", o.a->x = " << o.a->x
<< ", o.b->y = " << o.b->y << ", o.b->z = " << o.b->z
<< std::endl;
}
The approach depends on the task and using of the objects.
You are correct in both your assumptions.
As long as these three structures are defined in this order no further declarations have to be made.
Welcome to c++.
The biggest favour you will do yourself is to learn about the smart pointers early on.
It's almost always a mistake to write structures in terms of raw pointers.
#include <memory>
#include <iostream>
struct inner1 {
inner1(int a, int b) : w(a), x(b) {}
int w;
int x;
};
struct inner2 {
inner2(int a, int b) : y(a), z(b) {}
int y;
int z;
};
struct outer{
outer(int w, int x, int y, int z)
: a(std::make_unique<inner1>(w,x))
, b(std::make_unique<inner2>(y,z))
{}
std::unique_ptr<inner1> a;
std::unique_ptr<inner2> b;
};
int main()
{
auto p_outer = std::make_unique<outer>(1, 2, 3, 4);
return 0;
// p_outer.a and .b are destroyed automatically here
// and all memory is reclaimed.
}
I have been trying to understand this but can't get it to work. My impression is that this should work:-
template <int I> struct banana {
int getNumber() { return 5; }
int getNumber<0>() { return 6; }
};
So if I make a new banana with any template parameter other than 0, getNumber() should return 5 and if the parameter is 1, it should return 6. Why is it not working?
Because that's not the way to specialize. What you need is
#include <iostream>
template <int I> struct banana {
int getNumber() { return 5; }
//int getNumber<0>() { return 6; } // WRONG
};
template<> int banana<0>::getNumber(){ return 6;} // CORRECT WAY OF SPECIALIZING
int main()
{
banana<42> foo;
banana<0> bar;
std::cout << foo.getNumber() << std::endl; // outputs 5
std::cout << bar.getNumber() << std::endl; // outputs 6
}
Live on Coliru
There are 2 ways to get what you want... depending on what you want.
expanding on vsoftco's answer:
#include <iostream>
template <int I>
struct banana {
int getNumber() { return 5; }
};
template<>
struct banana<0>
{
int getNumber() { return 6; }
};
struct banana2
{
template<int I> int getNumber() { return 5; }
};
template<>
int banana2::getNumber<0>() { return 6; }
using namespace std;
auto main() -> int
{
banana<42> foo;
banana<0> bar;
std::cout << foo.getNumber() << std::endl;
std::cout << bar.getNumber() << std::endl;
banana2 b2;
std::cout << b2.getNumber<400>() << std::endl;
std::cout << b2.getNumber<0>() << std::endl;
return 0;
}
expected output:
5
6
5
6
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;
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.