Do not use class member function inside class - c++

I want to write an object-oriented wrapper around old C-style functions, while keeping the actual function names the same. Take a look at an example:
#include <iostream>
void doStuff(int a, float b)
{
std::cout << "a = " << a << ", b = " << b << "\n";
}
class Stuff
{
private:
int a;
float b;
public:
Stuff(int newA, float newB) : a(newA), b(newB) { }
int getA() { return a; }
float getB() { return b; }
};
class Widget
{
public:
void doStuff(Stuff s)
{
doStuff(s.getA(), s.getB()); //error: no matching function for call to 'Widget::doStuff(int, float)'
}
};
int main()
{
Widget w;
w.doStuff(Stuff(42, 3.14f));
return 0;
}
In this example, void doStuff(int a, float b) is the old C-function. Because in my real code, its equivalent is in an external library/header file, I cannot change its name. Next, Stuff is a container for keeping the values void doStuff(int a, float b) needs. The important things happen in Widget: void Widget::doStuff(Stuff s) should be the actual wrapper. I now expect doStuff(s.getA(), s.getB()) to call the old C-style function void doStuff(int a, int b) but the compilation fails with the given error.
Is it possible to make this code work without changing the name of the both doStuff functions? One option I already thought of is surrounding void doStuff(int a, float b) by some namespace. This works, but seems like very bad practice to me.
My compiler is mingw-w64 with g++ 5.2.0, so C++11 and C++14 are available.

The doStuff(Stuff s) method in your class hides the global function doStuff(int a, float b). If you want to call the global doStuff function, you have to use the scope resolution operator :: (::doStuff(s.getA(), s.getB());)

Try making your call like this:
::doStuff(s.getA(), s.getB());

Related

Passing a member function pointer to a non-member function within another member function

I have a code similar to the minimal example below, where the function g is provided by a library and expects double (*)(double) as an argument. I cannot change this. The example code does not compile because the member has signature double (*C::)(double) as explained in e.g. this post, with a number of possible solutions.
#include <iostream>
double g(double (*f)(double x)) { return f(0); };
class C
{
public:
C(double b) { a = b; };
double f2() { return g(&f1); };
private:
double a;
double f1(double x) { return x + a; };
};
int main()
{
C c (1);
std::cout << c.f2() << std::endl;
return 0;
}
I wonder what the best way to implement this is given that I don't want to point to C::f1 outside the class but within another member function. As far as I understand, the member function C::f1 is not static since it is only fully known after an instance of the class is initialised. Since speed is also a concern: would this be a problem with any of the possible solutions proposed elsewhere for similar versions of this issue?
Make your f1 function static:
static double f1(double x) { return x + a; };
This gives it the same signature as what your g function expects. Since a static function does not have a hidden this pointer, you will have to find some other way to get the value of a into it.
Okay, based on the comments and ideas from the post mentioned before, I will suggest to change g as follows and add a wrapper function f2_wrapper.
#include <iostream>
double g(double (*f)(double x, void *context), void *context)
{
return f(0, context);
};
class C
{
public:
C(double b) { a = b; };
double f1(double x) { return x + a; };
double f2();
private:
double a;
};
double f2_wrapper(double x, void* context)
{
C *c = (C*) context;
return c->f1(x);
}
double C::f2() { return g(&f2_wrapper, this); }
int main()
{
C c (1);
std::cout << c.f2() << std::endl;
return 0;
}

Is there a better way to provide this function to a constructor?

I have a class A which has a constructor with a function argument: i.e.
class A {
public:
A(int (*f)(int);
};
I can create this class and have it use func() with, for example,
int func(int n);
A a(func);
I would like to invoke this class a number of times, but have it use internally func(n)+m instead of func(n). I would prefer not to change class A. I could create a new class to define the function I want
class B {
int (*func)(int n);
int m;
public:
B(int (*ff)(int),int mm) : func(ff),m(mm) {}
int myfunc(int n) { return(func(n)+m);
};
However, I don't think it is possible to convert a pointer to myfunc into a pointer with the required signature for A's constructor.
The way I have chosen is similar to the above, but with myfunc() and associated variables stored in the global space:
int m;
int (*func)(int);
int myfunc(int n) { return(func(n)+m); }
void setupmyfunc(int mm,int (*ff)(int)) { m=mm; func=ff; }
Then I can can create my A object with
setupmyfunc(m,func);
A a(myfunc);
This works, but seems inelegant to me. Is there a better way?
Stateless lambdas are implicitly convertible to function pointers so you can just use that without modifying your class A and without creating another class B. That is if I understood your question correctly.
class A {
public:
A(int (*f)(int)) {};
};
int func(int n) { return n * 10; }
auto test()
{
A a{[](int n) { return func(n) + 1; }};
}
std::function can hold callable objects (functions, function objects, member function pointers (with object to bind to), etc. It uses some type-erasure such that it can have this genericity, but comes at the cost of internal overhead to actually invoke it, often equivalent to a virtual function call.
Here's an example, where A takes a std::function, which allows you to pass in lambdas.
#include <functional>
#include <iostream>
class A {
std::function<int(int)> func_;
public:
A(std::function<int(int)> func) : func_(func) {}
int call(int x) {
return func_(x);
}
};
int foo(int x) {
return x * 123; // whatever
}
int main() {
// here's your wrapper function to do func(x)+m (m==9 in this case)
A obj([](int x) { return foo(x) + 9; });
int result = obj.call(123);
std::cout << result << '\n';
}
https://godbolt.org/z/94MfGM67K
Update:
Given the rejection of both answers so far, using std::function is out because it changes class A, and the obvious use of state-full lambdas for composition and capturing customization data is also out, you will need to get more creative and possibly ugly. If you can't change A, then you can't change the signature of the function passed to a, so making the lambda take its data as another argument is also out.
Seems to me that leaves just one thing: using state that is outside the function (i.e. global data or encoded in a template non-type template parameter) as a form of pseudo-capture that an otherwise stateless function can use. I reject the global approach in general, though there's interesting aspects to it, and only present a template solution:
Now you write your free-standing functions and can compose them with a template:
#include <iostream>
using F = int(*)(int);
class A {
public:
A(F f) : f_(f) { }
int operator()(int x) { return f_(x); } // Added for demo
private:
F f_;
};
template <F FuncF, F FuncG>
int compose(int n) {
return FuncF(FuncG(n));
}
int func(int n) { return n * 1000; }
int add888(int n) { return n + 888; }
int add999(int n) { return n + 999; }
int main() {
A a1(compose<add888, func>);
A a2(compose<add999, func>);
std::cout << a1(1) << " " << a2(1) << " " << a1(1);
}
// output: 1888 1999 1888
https://godbolt.org/z/8KsqbTcTd
This works as far back as c++11, and replacing the "using" with "typedef" it work in C++98.

Function that does same things for different parameters

I have two functions that do the same thing: they add two numbers. One adds two numbers which are members of the class, the other adds numbers given by the user, outside the class.
Is there any way to write one single function that adds two numbers and checks whether the arguments are user input or class members?
void myclass::add(){
cout<<this->a+this->b;
}
void myclass::add(int a,int b){
cout<<a+b;
}
While you cannot really do it in a single function the common approach would be to write the more flexible of the two and use the other one just as a dispatcher:
void myclass::add(int a, int b) {
std::cout << (a+b);
}
void myclass::add() {
add(a,b);
}
Now, there are a different number of smells in this code... a function name reused to act on members or only inputs is one (a function that does not touch the object's state already smells at it not being a member, or being a static one). Printing inside a function called add (should it not return the values?)...
Disclaimer : I don't encourage such coding.
Ok, here's a method
void myClass::Add(int& a, int& b)
{
if (&a==&this->a)
{
std::cout << this->a + this->b
} else {
std::cout << a+b;
}
}
Ofc , things like myClass->Add(10,4) won't work... you will need some stack variables to hold the 10 and 4 variables.
So you want a single function that can have two different parameters? It isn't possible.
void myclass::add(int a, int b)
{
cout << a + b << endl;
}
Is what you want; but you can overload the function:
void myclass::add()
{
cout << memberA + memberB << endl;
}
In my opinion, this is a much better solution than having a single function that checks whether the variables are members or not; it makes your code readable. Don't be afraid to overload functions - it's one of those things that makes C++ awesome. I've created a class to demonstrate this:
class myClass
{
public:
myClass() : memberA(0), memberB(0) {}
~myClass() {}
void setNumbers(int a, int b)
{
memberA = a;
memberB = b;
}
void add(int a, int b)
{
cout << a + b << endl;
}
void add()
{
cout << memberA + memberB << endl;
}
private:
int memberA;
int memberB;
};
int main()
{
myClass m;
m.setNumbers(1, 2);
m.add();
return 0;
}
I've tested the add function with and without parameters and they both output the same result. The former because I used a setNumbers(..) function. Effectively, your first scenario of having two functions is the most apt solution to begin with.
In you realy wanted a single function, the way to do it is with optional default parameters.
Your declaration will be
void add(optional<int> a = optional<int>(), optional<int> b = optional<int>() );
Then in your implementation:
a ? a.get() : this->a
A benefit of this approach is that you can mix members and parameters. For example:
obj.add(1);
obj.add(optional<int>(), 2);

What are the rules for dynamic dispatching in c++?

I wonder how dynamic dispatching really works in C++. To illustrate my question, I will start by some Java code.
class A
{
public void op(int x, double y) { System.out.println("a"); }
public void op(double x, double y) { System.out.println("b"); }
}
class B extends A
{
public void op(int x, double y) { System.out.println("c"); }
public void op(int x, int y) { System.out.println("d"); }
}
class C extends B
{
public void op(int x, int y) { System.out.println("e"); }
}
public class Pol
{
public static void main(String[] args)
{
A a = new C();
B b = new C();
/* 1 */ a.op(2, 4);
/* 2 */ b.op(2.0, 4.0);
}
}
The call a.op(2, 4) will print "c", since indeed the compiler:
looks into Class A (since a is declared to be a variable of type A) which method is the closest to op(int, int),
can't find a op(int, int) method but finds the method op(int, double) (with a single auto-cast int -> double),
then fixes this signature.
During the execution, the JVM:
looks for a method with the signature op(int, double) fixed by the compiler into Class C but doesn't find it,
looks inside C's super-class, i.e., B,
and finally finds a method op(int, double), then calls it.
The same principle applies to the call b.op(2.0, 4.0), which prints "b".
Now, consider the equivalent code in C++
#include <iostream>
class A
{
public:
virtual void op(int x, double y) { std::cout << "a" << std::endl; }
virtual void op(double x, double y) { std::cout << "b" << std::endl; }
};
class B : public A
{
public:
void op(int x, double y) { std::cout << "c" << std::endl; }
virtual void op(int x, int y) { std::cout << "d" << std::endl; }
};
class C : public B
{
public:
void op(int x, int y) { std::cout << "e" << std::endl; }
};
int main()
{
A *a = new C;
B *b = new C;
/* 1 */ a->op(2, 4);
/* 2 */ b->op(2.0, 4.0);
delete a;
delete b;
}
a->op(2, 4) will print "c", like Java. But b->op(2.0, 4.0) outputs "c" again, and there, I'm lost.
What are exactly the rules applied at the compilation and during the execution in C++ for dynamic dispatching?
(Notice you will have the same behavior from the C++ code if you write virtual in front of each function; it changes nothing here)
For C++, when you do b->op(2.0, 4.0); the compiler looks in B, finds a method it can call (int x, double y) and uses it. It does not look in the superclass if any method in the subclass can handle the call. This is called method hiding, ie. op(double, double) is hidden.
If you want to make it select the (double x, double y) version, you need to make the function visible inside of B with the following declaration inside B:
using A::op;
Further explanation of the rules
By declaring a new overload to op in B you have hidden the base versions. The compiler will only dispatch based on 'B' which is why it selects op(int,double).
The compiler will warn/error on conversions if you tell it to. Using gcc, the compiler arguments -Wconversion -Werror will prevent your code from compiling, as you are right, there is a potential loss in precision here.
Given that you didn't turn on this compiler option, the compiler is happy to resolve your call to b->op(double, double) to B::op(int, double).
Please keep in mind that this is a compile time decision - not a runtime/polymorphic decision.
The actual vtable of the "b" pointer will have a method op(int, int) available at runtime, but the compiler doesn't know about this method at compile time. It only can assume that the b pointer is of type B*.
You start with the polymorphic behavior in your base class A. Then, using the same signature, you cannot stop this in the derived classes.
It's not necessary, if you declare the same method virtual or not.
You have to change the signature!
Furthermore, you have the visibility problem. This line
B *b = new C;
b->op(2.0, 4.0);
The compiler looks for a method within your class B. The op-methods hide the methods with the same name of class A (overload resolution). If he founds something useful, he is just using it.

Setting a pointer to a non-static member function

I'm trying to setup a function pointer that is set during execution based on a set of user parameters. I would like to have the function pointer point to a non-static member function but I can't find how to do it.
The examples I've seen say this can only be done with static member function only or use global variables in straight C.
A simplified example follows:
class CA
{
public:
CA(void) {};
~CA(void) {};
void setA(double x) {a = x; };
void setB(double x) {b = x; };
double getA(const double x) {return x*a; };
double getB(const double x) {return x*b; };
void print(double f(const double), double x) {
char cTemp[256];
sprintf_s(cTemp, "Value = %f", f(x));
std::cout << cTemp;
};
private:
double a, b;
};
The implementation part is
CA cA;
cA.setA(1.0);
cA.setB(2.0);
double (*p)(const double);
if(true) {
p = &cA.getA; //'&' : illegal operation on bound member function expression
} else {
p = cA.getB; //'CA::getB': function call missing argument list; use '&CA::getB' to create a pointer to member
//'=' : cannot convert from 'double (__thiscall CA::* )(const double)' to 'double (__cdecl *)(const double)'
}
cA.print(p, 3.0);
So how do I get p to point to either 'getA' or 'getB' so that it is still useable by 'print'.
From what I have seen, the suggestions are to use boost or std::bind but I've had no experience with either of these. I'm hoping that I don't need to dive into these and that I'm just missing something.
Compiler MSVC++ 2008
Don't forget that a member function accepts an implicit this parameter: therefore, a member function accepting a double can't be the same thing as a non-member (free) function accepting a double.
// OK for global functions
double (*p)(const double);
// OK for member functions
double (CA:*p)(const double);
Also the way you invoke them is different. First of all, with member functions, you need an object to invoke them on (its address will eventually be bound to the this pointer in the function call). Second, you need to use the .* operator (or the ->* operator if you are performing the call through a pointer):
p = &CA::getA;
CA cA;
(cA.*p)();
Consistently, you will have to change your definition of function print():
#include <iostream>
void print(double (CA::*f)(const double), double x)
{
// Rather use the C++ I/O Library if you can...
std::cout << "Value = " << (this->*f)(x);
};
So finally, this is how you should rewrite your main() function:
int main()
{
CA cA;
cA.setA(1.0);
cA.setB(2.0);
double (CA::*p)(const double);
if (true) // Maybe use some more exciting condition :-)
{
p = &CA::getA;
}
else {
p = &CA::getB;
}
cA.print(p, 3.0);
}
Compilation Issue
This answer focuses on the compilation issue presented in the question. I would not recommend implementing this as a solution.
Pointers to member functions are best dealt with with typedefs and a macro.
Here's the macro for calling a member function:
#define CALL_MEMBER_FN(object, ptrToMember) ((object).*(ptrToMember))
Source: [33.6] How can I avoid syntax errors when calling a member function using a pointer-to-member-function?, C++ FAQ.
This saves you having to remember the ugly (object).*(ptrToMember) syntax any time you wish to call a member function by pointer.
In your class, declare a typedef called CAGetter, this will make variable declaration much simpler:
class CA
{
public:
typedef double (CA::*CAGetter)(const double x);
Then you can declare your print() function quite simply:
void print(CAGetter f, double x)
The body is also simple, clear and concise:
{
std::cout << "value = " << CALL_MEMBER_FN(*this, f)(x) << '\n';
}
Sample usage:
CA a;
a.setA(3.1);
a.setB(4.2);
// Using a variable...
CA::CAGetter p = &CA::getA;
a.print(p, 1);
// without a variable
a.print(&CA::getB, 1);
// Calling the functions from outside the class...
std::cout << "From outside (A): " << CALL_MEMBER_FN(a, p)(10) << std::endl;
std::cout << "From outside (B): " << CALL_MEMBER_FN(a, &CA::getB)(10) << std::endl;
Design Issue
Passing a pointer to a member function into a method of an instance of the same class is a design smell (you wouldn't normally pass a member variable to a method, this is no different). There is not enough information in this question to address the underlying design issue but this problem could probably be solved with separate print() methods, a member variable or with inheritance and polymorphism.
You can either use pointer to method:
class CA
{
public:
typedef double (CA::*getter)( double );
CA(void) {};
~CA(void) {};
void setA(double x) {a = x; };
void setB(double x) {b = x; };
double getA(const double x) {return x*a; };
double getB(const double x) {return x*b; };
void print(getter f, double x) {
char cTemp[256];
sprintf(cTemp, "Value = %f", (this->*f)(x));
std::cout << cTemp;
};
private:
double a, b;
};
int main()
{
CA cA;
cA.setA(1.0);
cA.setB(2.0);
CA::getter p;
if(true) {
p = &CA::getA;
} else {
p = &CA::getB;
cA.print( p, 3.0 );
}
Or use boost::bind
class CA
{
public:
typedef boost::function<double( double )> getter;
CA(void) {};
~CA(void) {};
void setA(double x) {a = x; };
void setB(double x) {b = x; };
double getA(const double x) {return x*a; };
double getB(const double x) {return x*b; };
void print(getter f, double x) {
char cTemp[256];
sprintf(cTemp, "Value = %f", f(x));
std::cout << cTemp;
};
private:
double a, b;
};
int main()
{
CA cA;
cA.setA(1.0);
cA.setB(2.0);
CA::getter p;
if(true) {
p = boost::bind( &CA::getA, &cA, _1 );
} else {
p = boost::bind( &CA::getB, &cA, _1 );
}
cA.print( p, 3.0 );
}