Alias Declarations in C++ - c++

I have come across this code snippet and have no idea what it means:
#include <iostream>
int main(){
using test = int(int a, int b);
return 0;
}
I can guess test can be used instead of int(int a, int b), but what does int(int a, int b) even mean? is it a function? How can it be used?

int(int a, int b) is a function declaration that has two parameters of the type int and the return type also int.
You can use this alias declaration for example as a member function declarations of a class or using it in a parameter declaration.

It's an alias for a function signature.
A more complete usage is to declare a pointer or reference to a function
int foo(int, int);
int main()
{
using test = int(int a, int b); // identifiers a and b are optional
test *fp = &foo;
test *fp2 = foo; // since the name of function is implicitly converted to a pointer
test &fr = foo;
test foo; // another declaration of foo, local to the function
fp(1,2); // will call foo(1,2)
fp2(3,4); // will call foo(3,4)
fr(5,6); // will call foo(5,6)
foo(7,8);
}

Just to give another use option of this line, with lambda expressions:
int main() {
using test = int(int, int);
test le = [](int a, int b) -> int {
return a + b;
}
return 0;
}
One point that you have to keep in mind about this use of test, there are probably more efficient ways to declare a function signature, like auto in lambda expressions case, template in case of passing function as argument to another function, etc.
This way came all the way from pure C programming, with the using twist. I won't recommend of choosing this way, but for general understanding it is always good to know more than the correct ways.

Related

How to call function pointer for class member function

I tried to implement a function pointer calling to the class member. I have implemented the sample and assigned the function pointer successfully. But if I try to call the function pointer it is throwing an error. Kindly refer below sample code of what I implemented and assist me on this.
#include <iostream>
using namespace std;
class myfunpoin
{
public:
int addd(int a,int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
};
int main()
{
myfunpoin a;
int (myfunpoin::*myval)(int, int);
myval =&myfunpoin::addd;
myval(1, 2);//i want to invoke this function pointer but getting error
getchar();
return 0;
}
myval(1, 2);
This cannot work because you haven't passed the implicit instance argument.
A pointer to member function is called like a member function, except in place of the function name, you have indirection operator and the pointer to member function. Example:
(a.*myval)(1, 2);
The parenthesis are needed because function call operator has higher precedence and the expression would have a wrong meaning otherwise.

Passing a member function as arguments using pointer-to-member-function C++

I am trying to pass a member function as argument using pointer-to-member-function. I have already seen some links like this here but I could not solve the problem.
The class Foo has two member functions. I need to pass the addition function as an argument to the NewOper function.
This is my code. I can correctly use pointer to call the addition function but it gives me an error when I try to pass it as an argument to NewOper function. I appreciate it if you tell me how I can fix it. (The last two lines cause error)
#include <iostream>
using namespace std;
class Foo{
public:
int addition(int a, int b)
{
return (a + b);
}
int NewOper(int x, int y, int(*fnc2call)(int, int))
{
int r;
r = (*fnc2call)(x, y);
return (r);
}
};
int main()
{
int m,n, k, l;
int (Foo::*fptr) (int, int) = &Foo::addition;
Foo obj;
m=(obj.*fptr)(1,2);
Foo* p = &obj;
n=(p->*fptr)(3,4);
cout << m << endl;
cout << n << endl;
//**********************
int (Foo::*fptr) (int, int, int(*fnc2call)) = &Foo::NewOper;
k = (obj.*fptr)(1, 2, addition);
}
You already have answer in your own code:
int (Foo::*fptr) (int, int) = &Foo::addition - here you correctly declared fptr as pointer to function, which is (non static) member of class Foo
But you forgot to do the same in you NewOper function definition:
int NewOper(int x, int y, int(*fnc2call)(int, int)) - this function wants address of free function as 3rd argument. Redefine it in the same way you declared fptr. But then you'll need to pass also pointer to an object of class Foo to this function
Alternatively, you can make your function addition function static as Jarod42 suggested (actually, the way it is written now, there is no reason for it to be member of class Foo unless you have further plan on it). Then you'll need to remove Foo:: from fptr definition

How do I call this function?

I'm reading a lot about "typedef functions", but I getting casting errors when I try to call this one. What's the correct syntax to call this function?
typedef ::com::Type* Func(const char* c, int i);
that statement makes Func a type. Then you'll have to say Func *f = anotherFunc given another func is defined as : ::com::Type* anotherFunc(const char *c, int i){ /*body*/ }
Then you can call f("hello", 0) and it should work.
There's no function in your code. There's only a type name Func that stands for function type. There's nothing to call there.
The name Func, as defined in your question, can be used in several different ways.
For example, you can use it to declare a function
Func foo;
The above is equivalent to declaring
::com::Type* foo(const char*, int);
This will also work for member function declarations. (However, you can't use it to define a function).
For another example, you can use it when declaring a pointer to a function, by adding an explicit *
Func *ptr = &some_other_function;
The above is equivalent to declaring
::com::Type* (*ptr)(const char*, int) = &some_other_function;
For yet another example, you can use it as a parameter type in another function
void bar(Func foo)
in which case the function type will automatically decay to function pointer type, meaning that the above declaration of bar is equivalent to
void bar(Func *foo)
and equivalent to
void bar(::com::Type* (*foo)(const char*, int));
And so on.
In other words, show us what your are trying to do with it. As is your question is too broad to be answered specifically.
typedef function syntax:
#include <iostream>
using namespace std;
int add(int a, int b) {return a+b;}
typedef int(*F)(int a, int b);
int main() {
F f = add;
cout << f(1,2) << endl;
return 0;
}
The break down of typedef int(*F)(int a, int b);
The type name is F in brackets
Return type is the int at the beginning.
The parameters are (int, int)
Usage F f = &add;:
F is our type.
f is the variable name.
add is the function with the correct signature.
A valid syntax in your case would be: typedef ::com::Type (*Func)(const char* c, int i);

Function pointers to member functions

There are several duplicates of this but nobody explains why I can use a member variable to store the pointer (in FOO) but when I try it with a local variable (in the commented portion of BAR), it's illegal. Could anybody explain this?
#include <iostream>
using namespace std;
class FOO
{
public:
int (FOO::*fptr)(int a, int b);
int add_stuff(int a, int b)
{
return a+b;
}
void call_adder(int a, int b)
{
fptr = &FOO::add_stuff;
cout<<(this->*fptr)(a,b)<<endl;
}
};
class BAR
{
public:
int add_stuff(int a, int b)
{
return a+b;
}
void call_adder(int a, int b)
{
//int (BAR::*fptr)(int a, int b);
//fptr = &BAR::add_stuff;
//cout<<(*fptr)(a,b)<<endl;
}
};
int main()
{
FOO test;
test.call_adder(10,20);
return 0;
}
Apparently, you misunderstand the meaning of this->* in the call in FOO.
When you use this->* with the member fptr pointer, the this->* part has absolutely nothing to do with fptr being a member of FOO. When you call a member function using a pointer-to-member, you have to use the ->* operator (or .* operator) and you always have to specify the actual object you want to use with that pointer-to-member. This is what the this->* portion of the calling expression does. I.e. the call will always look as
(<pointer-to-object> ->* <pointer-to-member>) (<arguments>)
or as
(<object> .* <pointer-to-member>) (<arguments>)
The left-hand side of the call (<pointer-to-object> or <object> above) cannot be omitted.
In other words, it doesn't matter whether fptr is a member variable, local variable, global variable or any other kind of variable, the call through fptr will always look as
(this->*fptr)(a, b);
assuming that you want to invoke it with *this object. If, for another example, you want to invoke it for some other object pointed by pointer pfoo, the call will look as follows
FOO *pfoo;
...
(pfoo->*fptr)(a, b);
In your BAR class the call should look as (this->*fptr)(a,b) even though fptr is a local variable.
When you use a member function pointer, you need to specify the object on which it is acting.
I.e. you need to create a pointer to an instance of BAR (let's call it bar) and do:
(bar->*fptr)(a,b)
to call the function, or an instance of BAR and do:
(bar.*fptr)(a,b)
Put another way:
#include <iostream>
class BAR
{
int i;
public:
BAR(): i(0) {};
int AddOne() { return ++i; };
int GetI() { return i; };
}
int main()
{
BAR bar;
auto fPtr = &BAR::AddOne; // This line is C++0x only (because of auto)
std::cout << (bar.*fPtr)(); //This will print 1 to the console
std::cout << std::endl;
std::cout << bar.GetI(); //This will also print 1 to the console.
}
I don't think the usage of the variable itself is illegal. What's illegal is trying to call that method without a class instance.
That is, you should really call (someVar->*fptr)(a,b) where someVar is of type BAR*
BAR::call_adder() had a couple of problems. For one, you were mixing case. In C++, case is signifigant. BAR and bar are not the same. Second, you decalred and assigned the pointer fine, after fixing the case problems, but when you try to call through the pointer to a member function, you need to use operator ->* with a class object. Here's is call_adder() fixed
void call_adder(int a, int b)
{
int (BAR::*fptr)(int a, int b);
fptr = &BAR::add_stuff;
cout<<(this->*fptr)(a,b)<<endl;
}
When you invoke a member function of a class the compiler generates code to set 'this' while the function runs. When you call it from a function pointer that isn't done. There are ways to get around it but they aren't 'guaranteed' to work and are compiler dependent. You can do it as long as you're careful and know the possible problems you can run into.

C++ Lite Question 10.19. Function instead of variable decl

I had this problem happen to me in the past http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.19
My question is, when writing
Foo x(Bar());
Why is it "declaring a non-member function that returns a Bar object" ? i can understand it if i wrote
Foo x(Bar);
But what does it think the () means in Bar()?
Bar() there means "a function that takes no arguments and returns Bar". Consider a declaration of such a function:
Bar GetBar();
if you remove the name of the function from this, what remains will describe the function type. Some examples of where it's used is in template arguments; e.g. you can write this:
std::function<int(float)> f1;
std::function<Bar()> f2;
Hopefully this explains the syntax in general. Now what this means in this particular case. When a function type is used as a type of function argument, it is automatically subsituted for a function pointer type. So the equivalent (but clearer) declaration would be:
Foo x(Bar(*)());
Consider the following more simple example:
void fn1(int a)
{
}
fn1 is a function that takes a single int paramter.
Now take a look at fn2:
//Same as typing void fn2(int (*b)())
void fn2(int b())
{
}
Here fn2 does not take in an int, but it takes in a function that returns an int.
Now if you wanted to declare fn1 you could type it like so:
void fn1(int);//ommit the parameter name
And you can also declare fn2 like so:
void fn2(int());
Example usage:
#include <iostream>
int a()
{
sd::cout<<"hi"<<std::endl;
return 0;
}
void fn2(int b())
{
b();
}
int main(int argc, char **argv)
{
fn1(3);
fn2(a);
}
Output will be:
hi
Now there is one more topic to understand... You can forward declare functions with scope.
a.cpp:
void a()
{
void c();
c();
}
//void b()
//{
// c();//<--- undeclared identifier
//}
int main(int argc, char**argv)
{
a();
return 0;
}
c.cpp
#include <iostream>
void c()
{
std::cout<<"called me"<<std::endl;
}
g++ a.cpp c.cpp
./a.out
Output will be:
Called me
And tying it all together. If you do this:
int main(int argc, char**argv)
{
int b();
return 0;
}
You are forward declaring a function called b() that returns type int and takes no parameters
If you would have done b = 3; then you'd get a compiling error as you can't assign a value to a forward declared function.
And once you've read all that it becomes clear:
Foo x(Bar());
You are forward declaring a function x that returns a type Foo and takes in a parameter to a function that returns a type Bar.
Unfortunately it doesn't seem to be online, but Scott Meyers' book, Effective STL, has a good, detailed explanation of what's going on in your example in Item 6: Be alert for C++'s most vexing parse.
On the plus side, the book is worth the price for anyone serious about C++.