What does ampersand before closing bracket do in C++ function declaration? - c++

Found this example and wonder what the & before the closing bracket does?
void f(const Foo &)
{
std::cout << "f(const Foo&)\n";
}
Example taken from here
Help will be much appreciated.

In C++, if you don't use a parameter, you don't have to name it. Some compiler settings even generate warnings if you do name them. An unnamed parameter only consists of a type and the type can also be a pointer or a reference or combinations of them. In this case (as already answered), the type is a reference.
Unused parameters are mostly useless and should be avoided, but they can exist in virtual functions, where some implementations need them and others don't.

Its a reference to type Foo. You should get yourself a C++ book and read through it.
http://en.wikipedia.org/wiki/Reference_%28C%2B%2B%29

In simple terms the & says it's a reference.
So when you use the & operator in the function declaration, preceded by a type(here it is Foo) it means "reference to" which is essentially an automatically dereferenced pointer with disabled pointer arithmetic.
Also check this reference for details

Related

What does void*(*void)(void*) stands for?

And what's the difference between
void*(*void)(void*)
and
void*(*voi)(void*)
and when to use it?
well void*(void)(void) doesn't compile, because it tries to declare a function that returns a void* named void and you can't use keywords of the language as names.
you can't declare an int named void either (int void=5; doesn't work of course).
Now voi is a valid identifier and you can name a function voi.
Trying to get at what you're actually asking the difference between.
void(*name)(void); and void(name)(void); is that one declares a function and the other declares a function pointer.
In fact the brackets on the second example don't do anything. void(name)(void); is the same as void name(void);.
However when declaring function pointers the brackets are needed or the * will bind left to the return type.
Anyway, I'm not sure what exactly you're asking, so you're best off searching the site for other questions regarding function pointers. Like this one that also explains why using void(name)(void) can be different from void(name)().

If ampersands aren't needed for function pointers, why does boost::bind require one?

I've always believed that function pointers don't require an ampersand:
Do function pointers need an ampersand
Yet, every example I've seen of using boost::bind shows one, and my compiler - in most situations - gives a typically inscrutable error message if it's omitted.
synchronize(boost::bind(&Device::asyncUpdate , this, "ErrorMessage")); // Works
synchronize(boost::bind(Device::asyncUpdate , this, "ErrorMessage")); // Fails
Am I wrong in assuming that boost::bind's first parameter is basically function pointer?
Function pointers don't need it, member function pointers do.
Device::asyncUpdate is member function, as you could guess because it is being bound to this.
Here's a normative quote from n3337, 5.3.1/4
A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed in parentheses.

What are the uses of the type `std::nullptr_t`?

I learned that nullptr, in addition to being convertible to any pointer type (but not to any integral type) also has its own type std::nullptr_t. So it is possible to have a method overload that accepts std::nullptr_t.
Exactly why is such an overload required?
If more than one overload accepts a pointer type, an overload for std::nullptr_t is necessary to accept a nullptr argument. Without the std::nullptr_t overload, it would be ambiguous which pointer overload should be selected when passed nullptr.
Example:
void f(int *intp)
{
// Passed an int pointer
}
void f(char *charp)
{
// Passed a char pointer
}
void f(std::nullptr_t nullp)
{
// Passed a null pointer
}
There are some special cases that comparison with a nullptr_t type is useful to indicate whether an object is valid.
For example, the operator== and operator!= overloads of std::function could only take nullptr_t as the parameter to tell if the function object is empty. For more details you could read this question.
Also, what other type would you give it, that doesn't simply re-introduce the problems we had with NULL? The whole point is to get rid of the nasty implicit conversions, but we can't actually change behaviour of old programs so here we are.
The type was introduced to avoid confusion between integer zero and the the null memory. And as always cpp gives you access to the type. Where as Java only gives you access to the value. It really doesnt matter what purpose you find for it. I normally use it as a token in function overloading.
But I have some issues with the implementation of cpp null const.
Why didnt they just continue with NULL or null? That definition was already being used for that purpose. What about code that already was using nullptr for something else.
Not to mention nullptr is just too long. Annoying to type and ugly to look at most times. 6 characters just to default initialize a variable.
With the introduction of nullptr, you would think zero would no longer be both a integer and null pointer const. However zero still holds that annoying ambiguity. So I dont see the sense then of this new nullptr value. If you define a function that can accept an integer or a char pointer, and pass zero to that function call, the compiler will complain that it is totally ambigious! And I dont think casting to an integer will help.
Finally, it sucks that nullptr_t is part of the std namespace and not simply a keyword. Infact I am just learning this fact, after how long I have been using nullptr_t in my functions. MinGW32 that comes with CodeBlocks allows you to get away with using nullptr_t with std namespace. Infact MinGW32 allows void* increment and a whole lot of other things.
Which leads me to: cpp has too much denominations and confusion. To the point where code compatibility with one compiler is not compatibility with another of the same cpp version. Static library of one compiler cannot work with a different compiler. There is no reason why it has to be this way. And I think this is just one way to help kill cpp.

xcode - "attempt to use a deleted function" - what does that mean?

I am writing a C++ library in Xcode 4.2.
One of my classes won't compile with this error:
attempt to use a deleted function
There is no specific indication what function it's talking about.
I don't want to post the class code here, but does anybody have any idea what this error means?
I had a similar message with threads (C++11). It turned out that I was passing the wrong number of parameters to the function called by the thread so the thread did not find any function suitable and gave that message.
To add to Carlos' answer, I had the right number of arguments but one of the arguments was being passed by reference. Adding ref() around the variable fixed it for me. See here.
In C++11 you can declare functions as deleted:
struct Foo {
Foo(const Foo &) = delete;
};
Attempting to use such a function is an error. The purpose of doing this is so that, in this example, copy construction of this type is not possible. This is a more direct replacement for the non-copyable trick used pre-C++11.
Also, there are rules in the C++ spec that lead to member functions being implicitly deleted.
The error is telling you that your program attempts to use a deleted function. You'll have to post the error you're getting for more detailed help.
For me It solved it when I passed "this" pointer as a parameter to the function.
For me, the issue was that one of the arguments was a pointer, and I passed NULL directly as an argument. To solve this, I simply created a new NULL pointer which I passed to the function as an l-value instead.

(Obj) C++: Instantiate (reference to) class from template, access its members?

I'm trying to fix something in some Objective C++ (?!) code. I don't know either of those languages, or any of the relevant APIs or the codebase, so I'm getting stymied left and right.
Say I have:
Vector<char, sizeof 'a'>& sourceData();
sourceData->append('f');
When i try to compile that, I get:
error: request for member 'append' in 'WebCore::sourceData', which is of non-class type 'WTF::Vector<char, 1ul >& ()();
In this case, Vector is WTF::Vector (from WebKit or KDE or something), not STD::Vector. append() very much is supposed to be a member of class generated from this template, as seen in this documentation. It's a Vector. It takes the type the template is templated on.
Now, because I never write programs in Real Man's programming languages, I'm hella confused about the notations for references and pointers and dereferences and where we need them.
I ultimately want a Vector reference, because I want to pass it to another function with the signature:
void foobar(const Vector<char>& in, Vector<char>& out)
I'm guessing the const in the foobar() sig is something I can ignore, meaning 'dont worry, this won't be mangled if you pass it in here'.
I've also tried using .append rather than -> because isn't one of the things of C++ references that you can treat them more like they aren't pointers? Either way, its the same error.
I can't quite follow the error message: it makes it sound like sourceData is of type WTF:Vector<char, 1ul>&, which is what I want. It also looks from the those docs of WTF::Vector that when you make a Vector of something, you get an .append(). But I'm not familiar with templates, either, so I can't really tell i I'm reading that right.
EDIT:
(This is a long followup to Pavel Minaev)
WOW THANKS PROBLEM SOLVED!
I was actually just writing an edit to this post that I semi-figured out your first point after coming across a reference on the web that that line tells the compiler your forward declaring a func called sourceData() that takes no params and returns a Vector of chars. so a "non-class type" in this case means a type that is not an instance of a class. I interpreted that as meaning that the type was not a 'klass', i.e. the type of thing you would expect you could call like .addMethod(functionPointer).
Thanks though! Doing what you suggest makes this work I think. Somehow, I'd gotten it into my head (idk from where) that because the func sig was vector&, I needed to declare those as &'s. Like a stack vs. heap pass issue.
Anyway, that was my REAL problem, because I tried what you'd suggested about but that doesn't initialize the reference. You need to explicitly call the constructor, but then when I put anything in the constructor's args to disambiguate from being a forward decl, it failed with some other error about 'temporary's.
So in a sense, I still don't understand what is going on here fully, but I thank you heartily for fixing my problem. if anyone wants to supply some additional elucidation for the benefit of me and future google people, that would be great.
This:
Vector<char, sizeof 'a'>& sourceData();
has declared a global function which takes no arguments and returns a reference to Vector. The name sourceData is therefore of function type. When you try to access a member of that, it rightfully complains that it's not a class/struct/union, and operator-> is simply inapplicable.
To create an object instead, you should omit the parentheses (they are only required when you have any arguments to pass to the constructor, and must be omitted if there are none):
Vector<char, sizeof 'a'> sourceData;
Then you can call append:
sourceData.append('f');
Note that dot is used rather than -> because you have an object, not a pointer to object.
You do not need to do anything special to pass sourceData to a function that wants a Vector&. Just pass the variable - it will be passed by reference automatically:
foobar(sourceData, targetData);
Dipping your toes in C++ is never much fun. In this case, you've run into a couple of classic mistakes. First, you want to create an instance of Vector on the stack. In this case the empty () is interpreted instead as a declaratiton of a function called sourceData that takes no agruments and returns a reference to a Vector. The compiler is complaining that the resulting function is not a class (it's not). To create an instance of Vector instead, declare the instance without the () and remove the &. The parentheses are only required if you are passing arguments to the instance constructor and must be omitted if there are no arguments.
You want
Vector<char, sizeof 'a'> sourceData;
sourceData.append('f');
Vector<char, sizeof 'a'> outData; //if outData is not instantiated already
foobar(sourceData, outData);
This Wikipedia article gives a decent introduction to C++ references.