For the language difference (keeping only the function declarations below, since that's what's important only)
void execute( void (&func)() );
void g();
int main() {
void (*fp)() = g;
execute(fp); // doesn't work
execute(&g); // doesn't work either
execute(g); // works
}
It doesn't work, because it wants a function, not a function pointer. For the same reason that array answer rejects a pointer, this rejects a pointer too. You have to pass "g" directly.
For templates, it matters too
template<typename T>
void execute(T &t) { T u = t; u(); }
template<typename T>
void execute(T t) { T u = t; u(); }
Those two are very different from one another. If you call it with execute(g);
like above, then the first will try to declare a function and initialize it with t
(reference to g
). The generated function would look like this
void execute(void(&t)()) { void u() = t; u(); }
Now you can initialize references and pointers to functions, but of course not functions itself. In the second definition, T
will be deduced to a function pointer type by template argument deduction, and passing a function will convert it to that pointer parameter type implicitly. So everything will go fine.
I don't know why MSVC treats them differently for inlining - but i also suspect it's because function references appear more seldom.
In the first example, std::swap
is called, because of your using namespace std
.
The second example is exactly the same as the first one, so you might have no using.
Anyway, if you rename your function to my_swap
or something like that (and change every occurence), then the first code shouldn't work, as expected. Or, remove the using namespace std
and call std::cin
and std::cout
explicitly. I would recommend the second option.
Best Answer
passes a reference to an integer. This is an input/output parameter and can be used like a regular integer in the function. Value gets passed back to the caller.
passes a pointer to an integer. This is an input/output parameter but it's used like a pointer and has to be dereferenced (e.g.
*x = 100;
). You also need to check that it's not null.passes a pointer to a pointer to an integer. This is an input/output parameter of type integer pointer. Use this if you want to change the value of an integer point (e.g.
*x = &m_myInt;
).passes a reference to a pointer to an integer. Like above but no need to dereference the pointer variable (e.g.
x = &m_myInt;
).Hope that makes sense. I would recommend using typedefs to simplify the use of pointers and reference symbols.