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

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++.

Related

Alias Declarations in 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.

Instance of Most Vexing Parse with std::string and char*

This is a follow-up to my previous question: C++ compile error constructing object with rvalue std::string from which I learned about the Most Vexing Parse.
I understand now the gist of the problem, however there's one leftover item of syntax I still don't quite understand, which I'd like to ask as a standalone question, since the discussions on the previous post were getting quite long.
Given this code:
#include <iostream>
#include <string>
class Foo
{
public:
Foo(double d)
: mD(d)
{
}
Foo(const std::string& str)
{
try
{
mD = std::stod(str);
}
catch (...)
{
throw;
}
}
Foo(const Foo& other)
: mD(other.mD)
{
}
virtual ~Foo() {}
protected:
double mD;
};
class Bar
{
public:
Bar(const Foo& a, const Foo& b)
: mA(a)
, mB(b)
{
}
virtual ~Bar() {}
protected:
Foo mA;
Foo mB;
};
int main(int argc, char* argv[])
{
if (argc < 3) { return 0; }
Foo a(std::string(argv[1]));
Foo b(std::string(argv[2]));
Bar wtf(a, b);
}
I understand, now, that the line Foo a(std::string(argv[1])); can be interpreted as either:
(1) Create a Foo named a with an anonymous std::string that is created with a char*. (My desired interpretation)
or
(2) A declaration (not definition) for a function named a that takes a std::string*.
From answers to the original question, I learned that functions could be declared within the scope of another function. That was new to me, but seems within reason, I can buy it.
What I can't wrap my head around, though, is the interpretation of std::string(argv[1]) as a std::string*.
argv[1] is a char*, so I still don't see why the line isn't interpreted as an anonymous std::string being constructed with a char*. After all, I've used code analogous to the following hundreds of times without ever scrutinizing whether this would result in anything other than the construction of a std::string with its char* constructor:
#include <iostream>
int main()
{
char* pFoo[] = {"foo"};
std::string str(pFoo[0]);
std::cout << str << std::endl;
return 0;
}
I'm on the cusp of understanding the most vexing parse problem; if someone could further explain this last niggling part, that might help push me over the edge.
Thank you.
Foo a(std::string(argv[1]));
declares a function named a which returns Foo and has one parameter (named argv) of type std::string[1]. Since array function parameters are always replaced with pointer parameters, the actual type of the function parameter becomes std::string*.

C++ Function call via an object with public member pointer to function, without using dereference operator

Alright, I think the title is sufficiently descriptive (yet confusing, sorry).
I'm reading this library: Timer1.
In the header file there is a public member pointer to a function as follows:
class TimerOne
{
public:
void (*isrCallback)(); // C-style ptr to `void(void)` function
};
There exists an instantiated object of the TimerOne class, called "Timer1".
Timer1 calls the function as follows:
Timer1.isrCallback();
How is this correct? I am familiar with calling functions via function pointers by using the dereference operator.
Ex:
(*myFunc)();
So I would have expected the above call via the object to be something more like:
(*Timer1.isrCallback)();
So, what are the acceptable options for calling functions via function pointers, as both stand-alone function pointers and members of an object?
See also:
[very useful!] Typedef function pointer?
Summary of the answer:
These are all valid and fine ways to call a function pointer:
myFuncPtr();
(*myFuncPtr)();
(**myFuncPtr)();
(***myFuncPtr)();
// etc.
(**********************************f)(); // also valid
Things you can do with a function pointer.
1: The first is calling the function via explicit dereference:
int myfunc(int n)
{
}
int (*myfptr)(int) = myfunc;
(*myfptr)(nValue); // call function myfunc(nValue) through myfptr.
2: The second way is via implicit dereference:
int myfunc(int n)
{
}
int (*myfptr)(int) = myfunc;
myfptr(nValue); // call function myfunc(nValue) through myfptr.
As you can see, the implicit dereference method looks just like a normal function call -- which is what you’d expect, since function are simply implicitly convertible to function pointers!!
In your code:
void foo()
{
cout << "hi" << endl;
}
class TimerOne
{
public:
void(*isrCallback)();
};
int main()
{
TimerOne Timer1;
Timer1.isrCallback = &foo; //Assigning the address
//Timer1.isrCallback = foo; //We could use this statement as well, it simply proves function are simply implicitly convertible to function pointers. Just like arrays decay to pointer.
Timer1.isrCallback(); //Implicit dereference
(*Timer1.isrCallback)(); //Explicit dereference
return 0;
}
You don't have to dereference a function pointer to call it. According to the standard ([expr.call]/1),
The postfix expression shall have
function type or pointer to function type.
So (*myFunc)() is valid, and so is myFunc(). In fact, (**myFunc)() is valid too, and you can dereference as many times as you want (can you figure out why?)
You asked:
Timer1 calls the function as follows:
Timer1.isrCallback();
How is this correct?
The type of Timer1.isrCallback is void (*)(). It is a pointer to a function. That's why you can use that syntax.
It is similar to using:
void foo()
{
}
void test_foo()
{
void (*fptr)() = foo;
fptr();
}
You can also use:
void test_foo()
{
void (*fptr)() = foo;
(*fptr)();
}
but the first form is equally valid.
Update, in response to comment by OP
Given the posted definition of the class you would use:
(*Timer1.isrCallback)();
To use
(Timer1.*isrCallback)();
isrCallback has to be defined as a non-member variable of whose type is a pointer to a member variable of TimerOne.
void (TimerOne::*isrCallback)();
Example:
#include <iostream>
class TimerOne
{
public:
void foo()
{
std::cout << "In TimerOne::foo();\n";
}
};
int main()
{
TimerOne Timer1;
void (TimerOne::*isrCallback)() = &TimerOne::foo;
(Timer1.*isrCallback)();
}
Output:
In TimerOne::foo();
(Test this code)
If you want to define isrCallbak as a member variable of TimerOne, you'll need to use:
#include <iostream>
class TimerOne
{
public:
void (TimerOne::*isrCallback)();
void foo()
{
std::cout << "In TimerOne::foo();\n";
}
};
int main()
{
TimerOne Timer1;
Timer1.isrCallback = &TimerOne::foo;
// A little complicated syntax.
(Timer1.*(Timer1.isrCallback))();
}
Output:
In TimerOne::foo();
(Test this code)

What does operator()() in c++ do?

I'm new to C++11 thread , when reading a tutorial , I see a piece of code like this.
#include <thread>
#include <iostream>
using namespace std;
class background_task
{
public:
void operator()() const
{
cout<<"This is a new thread";
}
};
int main()
{
background_task f;
std::thread my_thread(f);
my_thread.join();
}
The output will be "This is new thread", but i don' really understand what does the function "operator()() const" mean?. In this case, it acts really the same with the constructor, is it right?.
And how can C++ have a syntax like that? I have search about related topic by using the search engine but no found no result.
Thanks in advanced.
void operator()() means an instance of the class with that operator can be called with function call syntax, with no return value, and without any parameters. For example:
background_task b;
b(); // prints "This is a new thread"
The operator() part indicates it is a call operator, the second set of empty parentheses () indicate the operator has no parameters. Here is an example with two parameters and a return value:
struct add
{
int operator()(int a, int b) const { return a + b; }
};
add a;
int c = a(1, 2); // c initialized to 1+2
Note that this syntax pre-dates C++11. You can create callable types (also referred to as functors) in C++03. The connection with C++11 is that the std::thread constructor expects something that can be called without arguments . This could be a plain function
void foo() {}
a static member function
struct foo {
static void bar() {}
};
an instance of a type such as background_task, a suitable lambda expression, a suitable invocation of std::bind, in short, anything that can be called without arguments.
It's just operator overloading and has nothing to do with C++11 or multi-threading. An overloaded operator is just a normal function with a funny name (this may be a bit oversimplified, but it's a good rule of thumb for beginners).
Your class has a function named (). That's all. Technically, you could as well have named the function foo or f or TwoParentheses.
Consider a simpler example:
#include <iostream>
class Example
{
public:
void operator()() { std::cout << "()"; }
void foo() { std::cout << "foo"; }
void TwoParentheses() { std::cout << "TwoParentheses"; }
};
int main()
{
Example e;
e.operator()();
e.foo();
e.TwoParentheses();
}
Now calling an overloaded operator like in this example in main, spelling out the entire .operator() part, is pretty pointless, because an overloaded operator's purpose is to make the calling code simpler. You would instead invoke your function like this:
int main()
{
Example e;
e();
}
As you can see, e(); now looks exactly as if you called a function.
This is why operator() is a special name, after all. In a template, you can handle objects with operator() and function pointers with the same syntax.
Consider this:
#include <iostream>
class Example
{
public:
void operator()() { std::cout << "Example.operator()\n"; }
};
void function() { std::cout << "Function\n"; }
template <class Operation>
void t(Operation o)
{
o(); // operator() or "real" function
}
int main()
{
Example object;
t(object);
t(function);
}
This is the reason why operator() is an important function in C++ generic programming, and is often required.
It has nothing to do with C++11, it's the function call overload operator. That means if you have a class like yours, you can create an instance of it and use as a function:
int main()
{
background_task bt;
bt();
}
The above main function should give the same result as your simple thread example.
it is operator over loading. the user provide an additional use to () operator. Example for static polymorphism. it is fearture of Object orieted program

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.