This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 3 years ago.
The other day i was trying to create an object by calling the default constructor of another class, and it ended up making a function declaration, Here is an example:
struct integer {
integer(){} //Default constructor.
};
struct rational {
rational(integer n, integer d){} //Default constructor.
};
void multiply(rational(), rational()) { //Valid syntax? Takes two function pointers.
}
rational one_half() {
return rational(integer(), integer()); //Here doesnt make a function declaration.
}
int main() {
rational num(integer(), integer()); //Here makes a function declaration,
//instead of constructing a rational object.
multiply(one_half, one_half); //function taking two function pointers.
}
Why does this happen? I know and can call the constructor like this integer::integer() but i would like to understand what's happening here and why integer() is behaving like integer(*)() in this example.
Why does this happen?
The rule comes from C, in C++ it works the same. From c++ standard dcl.fct inside a function parameter list:
... After determining the type of each parameter, any parameter of type “array of T” or of function type T is adjusted to be “pointer to T”. ...
Inside a function parameter list a parameter that has a type of function type integer() is converted to a pointer to that type integer(*)().
So is integer() in fact equal to integer(*)()?
Inside function parameter list, yes.
Related
This question already has answers here:
A confusing detail about the Most Vexing Parse
(4 answers)
Closed 3 years ago.
Taken directly from http://herbsutter.com/2013/05/09/gotw-1-solution/
While widget w(); is clear for me, I have no idea how can the below code be a function declaration?
// same problem (gadget and doodad are types)
//
widget w( gadget(), doodad() ); // pitfall: not a variable declaration
How is this possible?
In a function declaration, arguments of type array decay into pointers to the first element, arguments of type function decay into a function pointer, so the signature would be:
widget w( gadget(*)(), doodad(*)() );
That is, a function that takes as the first argument a pointer to a function taking no arguments and returning gadget, that takes as second argument a pointer to a function taking no arguments and returning a doodad and that the function itself returns a widget
There are even more interesting or confusing cases, like:
// assume 'x' is a variable defined somewhere:
widget w(gadget(x));
How could that be interpreted as a function declaration? I mean, x is a variable, right? Well, when declaring a variable you can add extra parenthesis, so gadget x; and gadget (x); both declare the same variable x. The same applies to function arguments so the code above looks like a declaration of a function that takes a first argument named x of type gadget and returns a widget...
It's function that gets two functions, that returns gadget and doodad and either of them gets no arguments.
Example that compiles fine.
#include <iostream>
class widget{};
class gadget{};
class doodad{};
gadget a(){}
doodad b() {};
widget w( gadget(), doodad() ){
}
int main() {
w(a,b);
return 0;
}
http://ideone.com/YjZK9Y
I am trying to use a pointer to a member function in my code so that I can easily replace the function to use without changing everywhere in the code. I get an error while compiling that I don't understand how to solve. Here is a minimum working example:
OrderBook.h
#include <list>
#include <string>
class Order
{
};
class OrderBook
{
typedef void(OrderBook::* MatchingAlgorithm)(Order&, std::list<Order>&);
public:
OrderBook(const std::string name);
void ExecuteFunction(Order&, std::list<Order>);
private:
void FunctionToUse(Order&, std::list<Order>&);
const std::string m_OrderBookName;
MatchingAlgorithm m_matchingAlgorithm;
};
OrderBook.cpp
#include "OrderBook.h"
OrderBook::OrderBook(
const std::string name
)
: m_OrderBookName(name)
{
m_matchingAlgorithm = &OrderBook::FunctionToUse;
}
void OrderBook::ExecuteFunction(Order & order, std::list<Order> listOfOrders)
{
(*m_matchingAlgorithm)(order, listOfOrders);
}
void OrderBook::FunctionToUse(Order &, std::list<Order>&)
{
// do nothing
}
Source.cpp
#include "OrderBook.h"
int main()
{
std::list<Order> mylist;
Order o1, o2;
mylist.push_back(o1);
mylist.push_back(o2);
OrderBook ob("my book");
ob.ExecuteFunction(o1, mylist);
return 0;
}
Compilation Errors
error C2171: '*': illegal on operands of type 'OrderBook::MatchingAlgorithm'
error C2064: term does not evaluate to a function taking 2 arguments
If I replace (*m_matchingAlgorithm) with FunctionToUse inside ExecuteFunction the code compiles without errors.
Change the function call to:
(this->*m_matchingAlgorithm)(order, listOfOrders);
Short answer
You can call your function using the pointer to member operator (.* or ->*):
void OrderBook::ExecuteFunction(Order & order, std::list<Order> listOfOrders)
{
(this->*m_matchingAlgorithm)(order, listOfOrders);
}
More info here.
Long explanations
We are all used to omit this-> for accessing members of the current object. The mecanism that allows this is name resolution principles. But these do not apply for pointer dereferencing operators.
The simple case of a pointer to a data member
Let's star with a simpler case : a pointer to an integer member.
class OrederBook {
...
int x,y;
int OrderBook::* px;
};
In the constructor you couldn't initialize px with &x because &x is an absolute address of an integer, and px is the (relative) address of an integer in an OrderBook. We would then initialize it:
OrderBook::OrderBook(..)
: m_OrderBookName(name), px(&OrderBook::x) {...}
But in this case, the ordinary dereferencing operator for px would not work either:
*px =2; // error because of unary operator *
In fact, for dereferencing such a pointer, you need to know not only the pointer, but also the object in which this pointer should be used:
this->*px =2; // yes ! take relative px address and apply it to this object.
Unary vs. Binary derefencing
The standard defines two different dereferencing operators:
5.3.1/1: The unary * operator performs indirection: the expression to which it
is applied shall be a pointer to an object type, or a pointer to a
function type and the result is an lvalue referring to the object or
function to which the expression points. If the type of the expression
is “pointer to T,” the type of the result is “T.”
5.5/3: The binary operator ->* binds its second operand, which shall be of type “pointer to member of T” to its first operand, which
shall be of type “pointer to T” or “pointer to a class of which T is
an unambiguous and accessible base class.” The expression E1->E2 is
converted into the equivalent form ((E1)).*E2.
Dereferencing a pointer to a member function
For the data example above, you have the choice of the weapons. You could build very easily code achieving the same results, but defining px as int *px instead of int OrderBook::*px and using the unary * as usual.
Unfortunately for poitners to non static member function, you can't use such shortcuts. You really need a pointer to a member function and not a pointer to a function: When you call a member function, in addition to the arguments that you have to pass, you always have to know for which object you call it. And the only way to tell this is to use (->*) or (.*).
Conclusion
Ommitting this->* and assuming the compiler would be intelligent enough to deduct that it's for the current object could seem natural for us. But this is not defined by the standard. It's unfortunate and more here.
This question already has answers here:
A confusing detail about the Most Vexing Parse
(4 answers)
Closed 3 years ago.
Taken directly from http://herbsutter.com/2013/05/09/gotw-1-solution/
While widget w(); is clear for me, I have no idea how can the below code be a function declaration?
// same problem (gadget and doodad are types)
//
widget w( gadget(), doodad() ); // pitfall: not a variable declaration
How is this possible?
In a function declaration, arguments of type array decay into pointers to the first element, arguments of type function decay into a function pointer, so the signature would be:
widget w( gadget(*)(), doodad(*)() );
That is, a function that takes as the first argument a pointer to a function taking no arguments and returning gadget, that takes as second argument a pointer to a function taking no arguments and returning a doodad and that the function itself returns a widget
There are even more interesting or confusing cases, like:
// assume 'x' is a variable defined somewhere:
widget w(gadget(x));
How could that be interpreted as a function declaration? I mean, x is a variable, right? Well, when declaring a variable you can add extra parenthesis, so gadget x; and gadget (x); both declare the same variable x. The same applies to function arguments so the code above looks like a declaration of a function that takes a first argument named x of type gadget and returns a widget...
It's function that gets two functions, that returns gadget and doodad and either of them gets no arguments.
Example that compiles fine.
#include <iostream>
class widget{};
class gadget{};
class doodad{};
gadget a(){}
doodad b() {};
widget w( gadget(), doodad() ){
}
int main() {
w(a,b);
return 0;
}
http://ideone.com/YjZK9Y
This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
Destructors of builtin types (int, char etc..)
Template Function:
template<typename T> void kill(T* type)
{
type->~T();
}
Call:
int x= 5;
kill(&x);
woah, it compiled!? How can a primitive type like int have a destructor? It is also working with char , bool etc.
§12.4.16 of the Standard says
16 [ Note: the notation for explicit call of a destructor can be used for any scalar type
name (5.2.4). Allowing this makes it possible to write code without having to know if a
destructor exists for a given type. For example,
typedef int I;
I* p;
p->I::~I();
—end note ]
The relevant part of the standard is §5.2.4/1:
The use of a pseudo-destructor-name after a dot . or arrow -> operator represents the destructor for the non-class type named by type-name. The result shall only be used as the operand for the function call operator (), and the result of such a call has type void. The only effect is the evaluation of the postfix expression before the dot or arrow.
This question already has an answer here:
Why doesn't reference-to-member exist in C++?
(1 answer)
Closed 9 years ago.
I recently find out that there is a reference-to-function concept in C++ :).
So as there are pointer-to-function and pointer-to-member-function different types. The question arises. Is there a "reference-to-member-function" concept?
I tried to compile the following code, but GCC 3.4.6 gives an error.
#include <iostream>
using namespace std;
class A {
public:
virtual void Af() const {
cout << "A::Af()" << endl;
}
};
int main() {
typedef void (A::& MemFnc)() const;
MemFnc mf = &A::Af;
A a;
(a.*mf)();
return 0;
}
There is no such a thing called reference to member in C++.
The language specification explicitly says in a note (§8.3.3/3 - 2003) that,
A pointer to member shall not point to a static member of a class (9.4), a member with reference type, or “cv void.” [Note: see also 5.3 and 5.5. The type “pointer to member” is distinct from the type “pointer”, that is, a pointer to member is declared only by the pointer to member declarator syntax, and never by the pointer declarator syntax. There is no “reference-to-member” type in C++.
No, references to member functions are not possible.
In some sense, the result of dereferencing a pointer to a member function could serve as one, but the only thing you can do with that result is to invoke a function call operator on it, per 5.5[expr.mptr.oper]/6. Nothing else is allowed.
There is no reference to member function.