what is the "&" behind variables in C++ templates? [duplicate] - c++

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What does “Class* &cls” mean in C++'s function definition?
i came across this code:
template <class T,class U> void inline TIntDataSwap2(U data,T i)
{
unsigned char*& data2=(unsigned char*&)data;
data2[0]=(unsigned char)(((unsigned int)i>> 8)&0xff);
data2[1]=(unsigned char)(((unsigned int)i>> 0)&0xff);
};
what is the meaning of the "&" behind "unsigned char *"?
can this only be used in templates? i have never seen it before and "& behind a variable" is hard to google up, please help me...

Reference operator - MSDN source.

The & is not "behind a variable" but part of the type.
You are probably already aware of what a reference is in C++. In this case, unsigned char *& is just a reference to a pointer to unsigned char.
This is completely independent of templates, and can be used inside or outside a template definition,

unsigned char*& is a reference to a pointer to a unsigned char. Always read the pointer/reference combination from right to left. This is in no way restricted to use within templates.
Normally when you pass an argument to a function, it is passed by value in C++ (even huge objects). A copy is made, which is what is passed to the function. This both consumes additional memory and prevents the function from modifying the argument you pass to it (since it only gets a copy). Using a reference, we don't make a copy so it is more memory efficient. It also allows the function to modify the argument if needed. If you only want the performance gain and don't want the function to modify the argument, you can declare the parameter a const reference.

Related

When and why should you use String&, String and Const?

I was working on a piece of code.
struct Argument
{
Argument(): s_name(""), name(""), optional(true) {}
Argument(String& s_name_inp, String& name_inp, bool optional_inp):s_name(s_name_inp),name(name_inp),optional(optional_inp){}
.....More code.....
}
Somewhere later in the code:
void addArgument(String& name_inp,bool optional=true)
{
String name;
//Creating a tmep string to store the corrected name if the user doesn't enter - or -- wrt. name of their argument.
name = isDashed(name_inp) ? name_inp : addDash(name_inp) ;
//using the dashed name to check if it's shortname or long name.
if(name.size()>3)
{
//This is the long name.
Argument arg("", name, optional);
insertArgument(arg);
}
else
{
//This is for the short name
Argument arg(name, "", optional);
insertArgument(arg);
}
}
Both Struct Argument and fn addArgument are part of a class where struct Argument is defined in the private and addArgument in the public.
It throws up an error when I run the code..
For Long name one-
error: no instance of constructor "ArgumentParser::Argument::Argument" matches the argument list
argument types are: (const char [1], ArgumentParser::String, __nv_bool)
For Short Name one -
error: no instance of constructor "ArgumentParser::Argument::Argument" matches the argument list
argument types are: (ArgumentParser::String, const char [1], __nv_bool)
I could figure out how to fix it. This error is coming because of the empty strings "" which I enter. Adding const in the struct Argument constructor fixes the problem.
struct Argument
{
Argument(): s_name(""), name(""), optional(true) {}
Argument(const String& s_name_inp, const String& name_inp, bool optional_inp):s_name(s_name_inp),name(name_inp),optional(optional_inp){}
.....More code.....
}
Similarly, declaring a String blank = "" ; and passing it while initializing an obj of struct Argument instead of "" curbs the problem as well. Also, passing String instead of String& in the Argument constructor also solves the issue-
Argument(String s_name_inp, String name_inp, bool optional_inp):s_name(s_name_inp),name(name_inp),optional(optional_inp){}
Thus what I concluded from this is that simply passing "" is a problem since it is not stored in some variable. It doesn't have some location which can be referenced(String&) in case a change is made inside the code. That's why adding a const before String& in the constructor ensures the compiler that no change will be made even though we are passing by ref, so the compiler allows the use of "".
However I do not understand why the compiler is being so 'smart' even though I haven't done any incorrect operation. It's like the compiler is popping bugs for 'security' also, apart from the usual 'errors' we make.
With this question, I also want to understand in a broader sense, the use of const.
I get that it's just for ensuring that no change will be made to the variable being passed(or returned) to a function/constructor. But why do we need it if I, as the programmer, can ensure that I won't be changing the variable. Why do we need const then?
One thing I know is, it can be used to tell others to keep a parameter unchanged if they see your code.(https://www.youtube.com/watch?v=4fJBrditnJU is a good source for learning about const) Also, what is the difference between use of const in these two cases -
int somefunc const(int& var)
{
// var=4; This isn't allowed due to the const in fn
return var;
}
int somefunc(const int& var)
{
// var =4 ; This is also not allowed.
return var;
}
Also, I want to know how passing by reference and passing by value differ if they are just being used for assignments, i.e, no change is being made to them but they are being used for checking conditions, or doing some assignments to other vars.
Adding const String& is like a surety that whatever the user is passing is not being tampered with, in the code, so can't we simply replace it with String? Because passing by value will instantiate a copy of the passed variable/parameter? Why do we use const String& then?
Another question about passing pointers and passing by reference: The only use I know of String&(or int& or any other) is to directly pass the actual 'thing' into the function, not a copy of it, so whatever we do with that 'thing' will be reflected on the original, just like we use pointers to get the changes to be made to the actual 'thing' and not a copy of it. Why don't we use pointers instead of passing by reference? What advantage does it bring?
I know this question is kind of vast but these are all interconnected questions. Answer to one compliments another. Thanks to anyone who takes the time to answer whatever they seems suitable!
Pointers and l-value references are exchangeable, for the most part. It's just less to write at the site of invocation.
The difference between const & and & comes, as you noticed, from a simple reference requiring a variable to reference. A reference with & has the semantic of "let me write that down for you". A const & allows the creation of the temporary copy on-the-fly, and has the semantic of "let me have a look". Pass by value has the meaning of "give me a copy, I decide what to do with it".
In practical experience, avoiding copies is your primary concern. So call-by-value is something you want to avoid for anything bigger than an integral value.
Const-correctness is mostly just design of the C++ language, it's not strictly required from a technical point of view. You can consider it to be a way of saying "trust me, I'm not going to break it".
About passing temporary values to a simple & parameter, think about it for a moment who actually owns the temporary, and for how long it's going to exist. Anything written to it, if you would be allowed to do so, would be lost.
Also think about default parameters, e.g. void foo(const bar &foobar = bar(42)). These are never allowed to be non-const references, as it would result in undefined behavior. That default object may live in a static scope (rather than every caller creating it anew), and someone messing with it would result in changing defaults. Good luck ever finding the cause for that bug.
Even for non-default parameters, const & allows the creation of the temporary at compile time (constexpr constructors), and also folding multiple instances of identical temporaries into a single instance in memory. This optimization would likewise not be possible without the guarantees made by const.
There is a plethora of other cases where const-correctness is also the key to enable compiler optimizations. So it's generally better to use correctly, even if you assumed that your code discipline would had prevented at least undefined behavior.
But why do we need it if I, as the programmer, can ensure that I won't be changing the variable. Why do we need const then?
You could also ensure to not make any errors in coding, so why compiler errors/warnings, unit tests, issue trackers, …
Why would you use the keyword const if you already know variable should be constant?
Use const wherever possible in C++?
Adding const String& is like a surety that whatever the user is passing is not being tampered with, in the code, so can't we simply replace it with String? Because passing by value will instantiate a copy of the passed variable/parameter? Why do we use const String& then?
A class could be more expensive to copy then the indirections over the reference are. Especially if the compiler would be able to inline the function in case of a const & for which no indirection would happen at all.
A copy could introduce unwanted side effects (could be problematic in an environment with limited resources)
A class could have a deleted copy constructor so no copy would be possible at all, but you still want to ensure const correctness.
The only use I know of String&(or int& or any other) is to directly pass the actual 'thing' into the function, not a copy of it, so whatever we do with that 'thing' will be reflected on the original, just like we use pointers to get the changes to be made to the actual 'thing' and not a copy of it. Why don't we use pointers instead of passing by reference? What advantage does it bring?
A pointer can accept a nullptr so you need to handle the case where nullptr is passed (if no nullptr must be passed gsl::not_null could be used). But using pointers would not allow passing temporaries.

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

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

Any reason to use (MFC) CList<T, T&> rather than CList<T, const T&>?

I've learned some guidelines that all told me pass a variable by reference should always use const, like func(const T& a). And I know the second template parameter in CList is a ARG_TYPE. Like CList::AddTail(ARG_TYPE item) would use ARG_TYPE as its parameter type.
I saw the sample codes in msdn shows me it uses the non-const Type as its second template argument. Any reasons to prefer this non-const Type as parameter type?
CList<string, &string> a; vs CList<string, const &string> b;
Any suggestion would be helpful. Thanks.
Programming C++ without const is like driving without the safety belt on.
1.It protects you from changing variables that aren't intended be changed,
2.It protects you from making accidental variable assignments
3.Accepting arguments by const reference gives you the efficiency of passing by reference with the safety of passing by value
At the same time, the compiler can generate more efficient code because it knows exactly what the state of the variable/function will be at all times. If you are writing tight C++ code, this is good.
Just for your reference I have read Inconveniences of const in this article, but its higly recommended to use const-correctness
http://duramecho.com/ComputerInformation/WhyHowCppConst.html

Why using const for arguments passed by value? [duplicate]

This question already has answers here:
Const correctness for value parameters
(6 answers)
Closed 9 years ago.
Say you have:
int f( const T a ) { ... }
int g( const T &a ) { ... }
I understand the use of const in g: we don't know how a is used outside the function, so we want to protect it from being modified. However I don't understand the use of const in f, where a is a local copy. Why do we need to protect it from being modified?
I can think of a few reasons:
1) When someone reads the code and see const T a, they know that a should not be modified in the body of the function.
2) The compiler will tell you when you try to modify a in the body of the function. Therefore, adding const can prevent mistakes.
BTW chris already mentioned this in the comments.
3) However, there is another difference in C++11. A constant object cannot be moved from, as a move operation modifies the object. Therefore, you can only make a copy of a in the function body and cannot move from it.
4) Also, if this is a class type, you cannot call non-const members functions on a const object.
Declaring variables const is a good practice.
WHY?
For arguments passed by value to functions, it doesn't matter for the caller whether you declare it const or not. The rationale here is to protect yourself from mistakes while coding, using the compiler to warn you that you are changing the value of a variable, so that you can explicitly confirm this behavior by removing the const modifier. This applies not only to function parameters, but also to local variables.
Based on this rationale, I personaly always start out by declaring all variables const and let the compiler to issue errors when I modify them. Then I check if this behavior is intended and remove the const modifier if it is indeed needed. For better legibility I also always prefer to code in a way my variables are all const.
"I personally tend to not use const except for reference and pointer parameters. For copied objects it doesn't really matter"
If you are using const in function argument there may be one of the following reason.
1-it help the compiler to optimize things a bit.
2-no body can modified argument value in future(if many people working on same code base)

What is the benefit of the const keyword in programming? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Sell me on using const correctness
I'm eager to know the answer. [to "What is the benefit of const keyword in programming?"]
const indicates that the value assigned to the variable cannot change. If you try to change the value you should get a compiler error.
The const keyword can declare a read only variable.
Using const parameters to a method tells you the method will not change the parameter.
A const method tells you that the method will not alter a class's member variables (but can change member variables marked as mutable)
You can also declare const pointers, better described here
What is the benefit of const keyword in programming?
Specifying a variable as const states that the variable's value should never change after the initial assignment. This allows the compiler to perform additional tests at compilation (validating your code).
For example, if a const function changes a (non-mutable) member in an object, the compiler will yield an error.
Benefit: You get more compile time checks to ensure that you're not changing data that shouldn't be changed.
Cost: You have to use it everywhere. If you need to, you can cast your way out of it, nullifying the benefits.
Getting usage right can be tricky with pointers. Is the pointer itself const, or the data it refers to? This is also the most common usage I've seen: you want to point to immutable memory.