Functions that cannot be overloaded in C++ - c++

Member function declarations with the same name and the name parameter-type-list cannot be overloaded if any of them is a static member function declaration. For example, following program fails in compilation.
#include<iostream>
class Test {
static void fun(int i) {}
void fun(int i) {}
};
int main()
{
Test t;
getchar();
return 0;
}
I don't understand why the following example can run:
#include<iostream>
class Test {
public:
static void fun(double i) {
std::cout << i << "\n";
}
void fun(int i) {
std::cout << i;
}
};
int main()
{
Test t;
t.fun(5.5);
t.fun(4);
return 0;
}

The second Example will run because the parameter types are different in both the function, i.e. double in the first and int in second. So function overloading takes place

Function overloading only works when you have different set of parameters, in the example's case it's int and double. change the parameter data type.

Related

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.

Call a C-style function address with std::bind and std::function.target using a method from object

I have a C-style function, which stores another function as an argument. I also have an object, which stores a method that must be passed to the aforementioned function. I built an example, to simulate the desired situation:
#include <functional>
#include <iostream>
void foo(void(*f)(int)) {
f(2);
}
class TestClass {
public:
std::function<void(int)> f;
void foo(int i) {
std::cout << i << "\n";
}
};
int main() {
TestClass t;
t.f = std::bind(&TestClass::foo, &t, std::placeholders::_1);
foo( t.f.target<void(int)>() );
return 0;
}
What is expected is that it will be shown on screen "2". But I'm having trouble compiling the code, getting the following message on the compiler:
error: const_cast to 'void *(*)(int)', which is not a reference, pointer-to-object, or pointer-to-data-member
return const_cast<_Functor*>(__func);
As I understand the use of "target", it should return a pointer in the format void () (int), related to the desired function through std :: bind. Why didn't the compiler understand it that way, and if it is not possible to use "target" to apply what I want, what would be the alternatives? I don't necessarily need to use std :: function, but I do need the method to be non-static.
This is a dirty little hack but should work
void foo(void(*f)(int)) {
f(2);
}
class TestClass {
public:
void foo(int i) {
std::cout << i << "\n";
}
};
static TestClass* global_variable_hack = nullptr;
void hacky_function(int x) {
global_variable_hack->foo(x);
}
int main() {
TestClass t;
global_variable_hack = &t;
foo(hacky_function);
return 0;
}
//can also be done with a lambda without the global stuff
int main() {
static TestClass t;
auto func = [](int x) {
t->foo(x); //does not need to be captured as it is static
};
foo(func); //non-capturing lambas are implicitly convertible to free functions
}

Member function not inherited? [duplicate]

This question already has an answer here:
Inheritance and method overloading
(1 answer)
Closed 6 years ago.
This is my code
class B {
public:
virtual void insert(int t, int p) = 0;
void insert(int t) {
insert(t, 0);
}
};
class D : public B {
public:
void insert(int t, int p) { }
};
int main() {
D d;
d.insert(1);
}
which won't compile. Sure, it will if I say d.B::insert(1) in main, but why is this incorrect as is? Thanks.
This is because in this case base class functions are not included in overload resolution. Similar situation is with functions declared in inner scope - they do not overload functions declared in outer scope (see examples below). You can imagine that derived class scope is nested inside base class scope.
Once compiler has found D::insert candidate it will not look further in base class. If there were no D::insert then compiler will look into base class for insert method to call. You can fix this by introducing insert function names from base class with:
using B::insert;
this will introduce all the B::insert overloaded functions in derived class. Or as you say, you can explicitly call base class method with:
d.B::insert(1)
Sample code to how overloading works in the same way in other contexts:
namespace Outer {
void foo(double d) {
std::cout << "Outer::foo(double d)\n";
}
namespace Inner {
//using Outer::foo; // uncomment to see "Outer::foo(double d)" in output
void foo(int n) {
std::cout << "Inner::foo(int n)\n";
}
void callMe() {
foo(1.1);
}
}
}
int main() {
Outer::Inner::callMe(); // Outputes: Inner::foo(int n)
}
or:
void foo(std::string s) {
std::cout << "foo(std::string s)\n";
}
void foo(double d) {
std::cout << "foo(double d)\n";
}
void foo(int n) {
std::cout << "foo(int n)\n";
}
int main() {
void foo(int d); // comment out to see foo(double d) in output
foo(1.1); // outputs: "foo(int n)", foo(double d) is hidden
//foo("hello"); // ups, it wont compile - name lookup in c++ happens before type checking
// commenting out `void foo(int d);` above will fix this.
}
I'm pretty sure it's because you redefined the function "insert" in D, which is the one that gets called. The function "insert" in the class "D" requires two parameters instead of one. By doing d.B::insert(1), you're calling "insert" in B.

Passing an inherited method to another method

I am trying to build a class that has a member function with a method as argument. The methods are defined in inherited classes. I build a minimal example:
#include <iostream>
struct base
{
base() {}
int number(int (*f)(int))
{
return f(1);
}
};
struct option1 : base
{
int timesTwo(int i){return 2*i;}
option1()
{
std::cout << number(timesTwo);
}
};
struct option2 : base
{
int timesThree(int i){return 3*i;}
int timesFour (int i){return 4*i;}
option2()
{
std::cout << number(timesThree);
}
};
int main()
{
option1 a; //I would expect this to print "2"
}
The current syntax in the function number is for a general function, but I cannot get it to work for a method of any inherited classes.
The problem here is that you're passing a pointer to a member function, which is completely different from a pointer to a non-member function (which is what your number function takes as an argument).
You could use std::function and std::bind:
int number(std::function<int(int)> f)
{
return f(1);
}
...
number(std::bind(&option1::timesTwo, this, _1));
You could also use templates, and extra arguments, like
template<typename T>
int number(T* object, int(T::*f)(int))
{
return (object->*f)(1);
}
...
number(this, &option1::timesTwo);
Or the simple (but not always correct, depending on situation and use case): Make the callback-function static:
static int timesTwo(int i){return 2*i;}
My recommendation is that you look over the solution using std::function, because then it's easy to call the number function with any type of callable object, like a lambda:
number([](int x){ return x * 2; });
The given error says :
error: reference to non-static member function must be called
You can just add static before your method members.
And I would suggest you to use std::function instead of pointer functions.
A working code :
#include <iostream>
#include <functional>
struct base
{
base() {}
int number(std::function<int(int)> f)
{
return f(1);
}
};
struct option1 : base
{
static int timesTwo(int i){return 2*i;}
option1()
{
std::cout << number(timesTwo);
}
};
struct option2 : base
{
static int timesThree(int i){return 3*i;}
static int timesFour (int i){return 4*i;}
option2()
{
std::cout << number(timesThree);
}
};
int main()
{
option1 a; // now it works
}

call a function N times by write N parentheses after the function

I want to implement the following:
I define a function. And when I write N ()'s after the function, the function will be called N times.
I give an example:
#include <iostream>
using namespace std;
typedef void* (*c)();
typedef c (*b)();
typedef b (*a)();
a aaa()
{
cout<<"Google"<<endl;
return (a)aaa;
}
int main()
{
aaa()()()();
system("pause");
}
Then the output is :
Are there any other methods to implement that?
It's simple using functors.
#include <iostream>
struct Function
{
Function& operator()() {
std::cout << "Google" << std::endl;
return *this;
}
};
int main()
{
Function f;
f()()()();
}
You might be interested in functors:
#include <iostream>
class my_functor {
public:
// if called without parameters
my_functor& operator()(){
std::cout << "print" << std::endl;
return *this;
}
// if called with int parameter
my_functor& operator()(int number){
std::cout << number << std::endl;
return *this;
}
};
int main(){
my_functor functor;
functor()(5)();
return 0;
}
By overloading the function call operator () you can add function-behaviour to your object. You can also define different parameters which shall be passed to your overloaded ()-operator and the respective function call will be invoked. Just make sure that you return a reference to this-instance, if you want to invoke the function call on the object instance, that was modified by the previous function call.