C++ Access member function using pointer - c++11

I am not able to access member function using pointer.Find the below code and Error message
The Error message is mentioned here
error: request for member ‘getstream’ in ‘* objA.A::getfunction()’, which is of non-class type ‘int’
ret = objA.getfunction()->getstream();
#include <iostream>
using namespace std;
class A {
public:
int *getfunction();
int getstream();
};
int* A::getfunction()
{
static int a;
a= getstream();
return &a;
}
int getstream()
{
return 1;
}
int main()
{
int *ret;
A objA;
ret = objA.getfunction()->getstream();
cout << ret;
return 0;
}

If you want to achieve a syntax like objA.getfunction()->getstream(); in your main function,
you can do it with class A implementation similar to this :
#include <iostream>
using namespace std;
// class A declaration
class A {
public:
// Nested class A::AFunction declaration
class AFunction {
public:
int getstream();
};
private:
AFunction *p_AFunction;
public:
A();
~A();
A::AFunction *getfunction();
}; // class A
// class A member function implementations
A::A() : p_AFunction(new AFunction()) {
}
A::~A() {
delete p_AFunction;
p_AFunction = nullptr;
}
A::AFunction *A::getfunction() {
return p_AFunction;
}
// Nested class A::AFunction member function implementations
int A::AFunction::getstream() {
return 1;
}
// main function
int main() {
A objA;
int ret = objA.getfunction()->getstream();
cout << ret;
return 0;
}
If you want A::getfunction() function to return a function pointer to a member function in class A, and then invoke it in main function, you can have a implementation similar to this :
#include <iostream>
using namespace std;
// class A declaration
class A {
public:
typedef int (A::*AMemberFuncPtr) ();
private:
AMemberFuncPtr fn_getstream;
public:
A();
A::AMemberFuncPtr getfunction();
private:
int getstream();
}; // class A
// class A member function implementations
A::A() : fn_getstream(&A::getstream) {
}
A::AMemberFuncPtr A::getfunction() {
return fn_getstream;
}
int A::getstream() {
return 1;
}
// main function
int main() {
A objA;
int ret = (objA.*objA.getfunction())();
cout << ret;
return 0;
}
Also see the answer to Function pointer to member function.

Related

Custom compare class not working as I expect for pointers to a user defined class in a std::set container

I can't figure out why in this code example the std::set container is not ordering the Entities as I expect on the basis of the compare class I defined. Anyone can help me please? Thanks
#include <iostream>
#include <set>
class Entity {
public:
int num;
Entity(int num):num(num){}
bool operator< (const Entity& _entity) const { return (this->num < _entity.num); }
};
struct my_cmp {
bool operator() (const Entity* lhs, const Entity* rhs) const { return (lhs < rhs); }
};
class EntityManager {
private:
std::set<Entity*, my_cmp> entities;
public:
void AddEntity(int num) { entities.insert(new Entity(num)); }
void ListAllEntities() const {
unsigned int i = 0;
for (auto& entity: entities) {
std::cout << "Entity[" << i << "]: num:" << entity->num << std::endl;
i++;
}
}
};
int main(void) {
EntityManager manager;
manager.AddEntity(2);
manager.AddEntity(1);
manager.AddEntity(4);
manager.AddEntity(3);
manager.ListAllEntities();
return 0;
}
Output:
Entity[0]: num:2
Entity[1]: num:1
Entity[2]: num:4
Entity[3]: num:3
I would expect the following output instead:
Entity[1]: num:1
Entity[0]: num:2
Entity[3]: num:3
Entity[2]: num:4
You need to dereference your pointers *lhs < *rhs. You're just comparing the value of the pointers currently, so your order is dependent on their location in memory.
#include <iostream>
#include <set>
class Entity {
public:
int num;
Entity(int num):num(num){}
bool operator< (const Entity& _entity) const { return (this->num < _entity.num); }
};
struct my_cmp {
bool operator() (const Entity* lhs, const Entity* rhs) const { return (*lhs < *rhs); }
};
class EntityManager {
private:
std::set<Entity*, my_cmp> entities;
public:
void AddEntity(int num) { entities.insert(new Entity(num)); }
void ListAllEntities() const {
unsigned int i = 0;
for (auto& entity: entities) {
std::cout << "Entity[" << i << "]: num:" << entity->num << std::endl;
i++;
}
}
};
int main(void) {
EntityManager manager;
manager.AddEntity(2);
manager.AddEntity(1);
manager.AddEntity(4);
manager.AddEntity(3);
manager.ListAllEntities();
return 0;
}
Demo

Can a method of an class (in a shared_ptr) be tied to a static function in a traits class?

Historically, I've been using trait classes to hold information and apply that into a "generic" function that runs the same "algorithm." Only differed by the trait class. For example: https://onlinegdb.com/ryUo7WRmN
enum selector { SELECTOR1, SELECTOR2, SELECTOR3, };
// declaration
template < selector T> struct example_trait;
template<> struct example_trait<SELECTOR1> {
static constexpr size_t member_var = 3;
static size_t do_something() { return 0; }
};
template<> struct example_trait<SELECTOR2> {
static constexpr size_t member_var = 5;
static size_t do_something() { return 0; }
};
// pretend this is doing something useful but common
template < selector T, typename TT = example_trait<T> >
void function() {
std::cout << TT::member_var << std::endl;
std::cout << TT::do_something() << std::endl;
}
int main()
{
function<SELECTOR1>();
function<SELECTOR2>();
return 0;
}
I'm not sure how to create "generic" algorithms this when dealing with polymorphic classes.
For example: https://onlinegdb.com/S1hFLGC7V
Below I have created an inherited class hierarchy. In this example I have a base catch-all example that defaults all the parameters to something (0 in this case). And then each derived class sets overrides specific methods.
#include <iostream>
#include <memory>
#include <type_traits>
#include <assert.h>
using namespace std;
struct Base {
virtual int get_thing_one() {
return 0;
}
virtual int get_thing_two() {
return 0;
}
virtual int get_thing_three() {
return 0;
}
virtual int get_thing_four() {
return 0;
}
};
struct A : public Base {
virtual int get_thing_one() override {
return 1;
}
virtual int get_thing_three() override {
return 3;
}
};
struct B : public Base {
virtual int get_thing_one() override {
return 2;
}
virtual int get_thing_four() override{
return 4;
}
};
Here I created a simple factory, not elegant but for illustrative purposes
// example simple factory
std::shared_ptr<Base> get_class(const int input) {
switch(input)
{
case 0:
return std::shared_ptr<Base>(std::make_shared<A>());
break;
case 1:
return std::shared_ptr<Base>(std::make_shared<B>());
break;
default:
assert(false);
break;
}
}
So this is the class of interest. It is a class does "something" with the data from the classes above. The methods below are a simple addition example but imagine a more complicated algorithm that is very similar for every method.
// class that uses the shared_ptr
class setter {
private:
std::shared_ptr<Base> l_ptr;
public:
setter(const std::shared_ptr<Base>& input):l_ptr(input)
{}
int get_thing_a()
{
return l_ptr->get_thing_one() + l_ptr->get_thing_two();
}
int get_thing_b()
{
return l_ptr->get_thing_three() + l_ptr->get_thing_four();
}
};
int main()
{
constexpr int select = 0;
std::shared_ptr<Base> example = get_class(select);
setter l_setter(example);
std::cout << l_setter.get_thing_a() << std::endl;
std::cout << l_setter.get_thing_b() << std::endl;
return 0;
}
How can I make the "boilerplate" inside the setter class more generic? I can't use traits as I did in the example above because I can't tie static functions with an object. So is there a way to make the boilerplate example more common?
Somewhere along the lines of having a selector, say
enum thing_select { THINGA, THINGB, };
template < thing_select T >
struct thing_traits;
template <>
struct thing_traits<THINGA>
{
static int first_function() --> somehow tied to shared_ptr<Base> 'thing_one' method
static int second_function() --> somehow tied to shared_ptr<Base> 'thing_two' method
}
template <>
struct thing_traits<THINGB>
{
static int first_function() --> somehow tied to shared_ptr<Base> 'thing_three' method
static int second_function() --> somehow tied to shared_ptr<Base> 'thing_four' method
}
// generic function I'd like to create
template < thing_select T, typename TT = thing_traits<T> >
int perform_action(...)
{
return TT::first_function(..) + TT::second_function(..);
}
I ideally would like to modify the class above to something along the lines of
// Inside setter class further above
int get_thing_a()
{
return perform_action<THINGA>(...);
}
int get_thing_b()
{
return perform_action<THINGB>(...);
}
The answer is, maybe I can't, and I need to pass int the shared_ptr as a parameter and call the specific methods I need instead of trying to tie a shared_ptr method to a static function (in hindsight, that doesn't sound like a good idea...but I wanted to bounce my idea)
Whoever makes the actual call will need a reference of the object, one way or the other. Therefore, assuming you want perform_action to perform the actual call, you will have to pass the parameter.
Now, if you really want to store which function of Base to call as a static in thing_traits without passing a parameter, you can leverage pointer to member functions:
template <>
struct thing_traits<THINGA>
{
static constexpr int (Base::*first_function)() = &Base::get_thing_one;
...
}
template < thing_select T, typename TT = thing_traits<T>>
int perform_action(Base & b)
{
return (b.*TT::first_function)() + ...;
}
You can also play instead with returning a function object that does the call for you (and the inner function takes the parameter).
It all depends on who you need to make the call and what information/dependencies you assume you have available in each class/template.

STD::FUNCTION C++

I'm still learning Modern C++ and I would like to clarify STD:FUNCTION,
Here is my sample code that works fine :
#include <iostream>
#include <functional>
using namespace std;
int func(function<bool()> foo) {
return 2;
}
struct fee {
bool operator()() {
return true;
}
};
int main() {
cout << func(fee());
}
It will display "2" on the console.
What I am wondering is why this does not work. I changed bool operator()() to bool operator()(int i).
#include <iostream>
#include <functional>
using namespace std;
int func(function<bool()> foo) {
return 2;
}
struct fee {
bool operator()(int i) {
return true;
}
};
int main() {
cout << func(fee());
}
The error says:
In function 'int main()':
18:20: error: could not convert 'fee()' from 'fee' to 'std::function<bool()>'
What should be the right thing to do ?
In the second example, the fee operator() function now takes an int as a parameter.
Therefore you need to change
int func(function<bool()> foo) {
return 2;
}
to
int func(function<bool(int)> foo) {
return 2;
}
to reflect that.

Error in storing outer class object in inner class C++

I was implementing the ring buffer and have encountered an error. What does it mean to store a reference of outer class(class ring) object(m_ring) in inner class(class iterator) and when I remove the reference(&) the program compiles correctly but crashes. Please explain what is happening.(See the comment in Ring.h) Sorry for bad English.
// Ring.h
#ifndef RING.H
#define RING.H
#include <iostream>
using namespace std;
template<class T>
class ring {
unsigned int m_size;
int m_pos;
T *m_values;
public:
class iterator;
public:
ring(unsigned int size) : m_size(size), m_pos(0)
{
m_values = new T[m_size];
}
~ring()
{
delete[] m_values;
}
void add(const T &val)
{
m_values[m_pos] = val;
m_pos++;
m_pos %= m_size;
}
T& get(int pos)
{
return m_values[pos];
}
iterator begin()
{
return iterator(0, *this);
}
iterator end()
{
return iterator(m_size, *this);
}
};
template<class T>
class ring<T>::iterator {
int m_pos;
ring &m_ring; // Removing & gives garbage output.
public:
iterator(int pos, ring& aRing) : m_pos(pos), m_ring(aRing){}
bool operator!=(const iterator &other) const
{
return other.m_pos != m_pos;
}
iterator &operator++(int)
{
m_pos++;
return *this;
}
iterator &operator++()
{
m_pos++;
return *this;
}
T &operator*()
{
// return m_ring.m_values[m_pos];
return m_ring.get(m_pos);
}
};
#endif // RING
Driver program :
// Ring_Buffer_Class.cpp
#include <iostream>
#include "ring.h"
using namespace std;
int main()
{
ring<string> textring(3);
textring.add("one");
textring.add("two");
textring.add("three");
textring.add("four");
// C++ 98
for(ring<string>::iterator it = textring.begin(); it != textring.end(); it++)
{
cout << *it << endl;
}
cout << endl;
// C++11
for(string value : textring)
{
cout << value << endl;
}
return 0;
}
I also observed that removing ~ring() (Destructor) results into correct output.
Expected output :
four
two
three
four
two
three

Hash table of templated functor

I want to create a hastable to member templated functor, I explain.
Here is my exemple which does'nt work:
#include <iostream>
#include <unordered_map>
using namespace std;
class MyFirstClass
{
int i_;
public:
MyFirstClass(): i_(0) {}
void setI(int i) { i_ = i; }
int getI() { return i_; }
};
class MySecondClass
{
bool b_;
public:
MySecondClass(): b_(0) {}
void setB(bool b) { b_ = b; }
bool getB() { return b_; }
};
template<class X, void (X::*p)()>
class MyFunctor
{
X& _x;
public:
MyFunctor(X& x) : _x( x ) {}
void operator()() const { (_x.*p)(); }
};
int main(int argc, char *argv[])
{
unordered_map<string,MyFunctor> myHashTable;
MyFirstClass first;
MyFirstClass second;
myHashTable["int"] = first::setI;
myHashTable["bool"] = second::setB;
//
string key = "bool";
int value = 1;
myHashTable[key](value);
return 0;
}
I have multiple class with their own setter . I would like to be able thanks to the has table and a command {string,int} change the value of the corresponding class.
The previous code is not working for the moment and I am stuck.
There are a few problems with your code, as it stands.
Firstly, from your example unordered_map<string,MyFunctor> doesn't name a type, because MyFunctor doesn't name a type. You could create a non-template base class with a virtual operator(), and then have MyFunctor inherit from it.
Second, you aren't using compatible method pointers, MyFirstClass::setI and MySecondClass::setB both take a parameter.
Third, related to the first, you have to specify the template parameters when constructing an object from a class template. (until c++17's class template deduction guides). You also have ungrammatical syntax that I assume is trying to specify the object argument to the MyFunctor constructor alongside the method-pointer template argument.
You would have something like
class MyFunctorBase {
virtual void operator()(void * i) const = 0;
}
template<class T, class X, void (X::*p)(T)>
class MyFunctor : public MyFunctorBase
{
X& _x;
public:
MyFunctor(X& x) : _x( x ) {}
void operator()(void * i) const override { (_x.*p)(*static_cast<T*>(i)); }
};
int main(int argc, char *argv[])
{
unordered_map<string,shared_ptr<MyFunctorBase>> myHashTable;
MyFirstClass first;
MyFirstClass second;
myHashTable["int"] = make_shared<MyFunctor<int, MyFirstClass, &MyFirstClass::setI>>(first);
myHashTable["bool"] = make_shared<MyFunctor<bool, MySecondClass, &MySecondClass::setB>>(second);
//
string key = "bool";
bool value = true;
(*myHashTable[key])(static_cast<void *>(&value));
return 0;
}
Or, much more easily, use the existing std::function, which does that for you
int main(int argc, char *argv[])
{
unordered_map<string,function<void(void *)>> myHashTable;
MyFirstClass first;
MyFirstClass second;
myHashTable["int"] = [first](void * i) { first.setI(*static_cast<int *>(i)); };
myHashTable["bool"] = [second](void * i) { second.setB(*static_cast<bool *>(i)); };
//
string key = "bool";
bool value = true;
myHashTable[key](static_cast<void *>(&value));
return 0;
}

Resources