What does '&' after class name mean? - c++11

#include <bits/stdc++.h>
int main () {
std::string foo = "string_1";
std::string bar = "string_2";
std::vector<std::string> myvector;
myvector.push_back (foo);
myvector.push_back (std::move(bar));
for (std::string x:myvector)
std::cout << x << '\n' ;
}
How's that code is diffrent when I exchange
for (std::string x:myvector)
for?
for (std::string& x:myvector)
I'm guessing there are a lot of places when I could find that, but I don't know what's the name of this measure, so I don't know what I should search for. Link to explanation will be enough if it's it's easier for you.
EDIT:
What's the diffrence between:
for(auto x:my_vector)
for(auto& x:my_vector)
for(auto&& x:my_vector)

What does '&' after class name mean?
The ampersand is part of the type in the declaration and signifies that the type is a reference. Reference is a form of indirection, similar to a pointer.
What's the diffrence between:
for(auto x:my_vector)
The loop variable is a non-reference. It will contain a copy of the object in the container.
for(auto& x:my_vector)
The loop variable is an lvalue reference. Since the variable references the objects in the container, they can be modified through that reference. This also avoids copying the objects, which may be advantageous if the copy is expensive.
for(auto&& x:my_vector)
The loop variable is a universal reference. This means that it will be either an lvalue or rvalue reference, depending on the type returned when the iterator of the container is dereferenced. As far as I know, there are only a few obscure cases where this is useful. You'll probably never need it.

Related

C++ why overloading (T&) in template with (T*)

in C++, if a method is accepting left reference + pointer only,
it seems it suffices if we only have a template method with T& as its parameter, why we usually overload with test(T* ) as well ?
proof of concept: left reference method can take pointer argument.
#include <iostream>
using namespace std;
template<class T>
void test(T& arg) {
T value = arg;
cout << *value << endl;
}
int main() {
int b = 4;
int* a = &b;
test(a); // compiles and runs without issue.
return 0;
}
Why [do] we usually overload with test(T* ) as well?
I am not sure that we usually do anything of the sort, but if one were to overload for a pointer, it would be because pointers behave differently than object types. Remember, a pointer in fact is not an object but an address to an object.
The reason that test(a) compiles and runs without issue is because it is accepting a reference to a pointer to an object as its parameter. Thus, when the line cout << *value << endl; executes, the pointer is dereferenced back to an object and we see 4 printed to standard out.
As #HolyBlackCat mentioned, we usually want do different things for T& and T*.
As indicated in the example, for test(T&) we usually need to manually do dereference, this would result in the difference in the behavior, so it makes sense to have a overload like this.

Access variables in struct from void pointer

I was wondering if there is a way to access a data member within a struct that is being pointed to by a void*? What I'm trying to explain will hopefully be more apparent in my example code:
int main()
{
struct S
{
int val;
};
S s;
s.val = 5;
void* p;
p = malloc(sizeof(S));
*(struct S*) p = s;
std::cout<< *(struct S*)p.val << std::endl;
}
I have ran this exact code casting p as *(int*)p and it printed fine, however, using exact code above results in a compilation error. Haven't been able to find an example that quite accomplishes this task. Is it possible to access the data members of the struct after it is casted? why or why not? if so, how?
The . operator has higher precedence than a C-style cast. So *(struct S*)p.val is treated as *((struct S*)(p.val)), which doesn't make sense since p is a pointer and does not have members.
So you need parentheses to specify what you intended:
std::cout<< (*(struct S*)p).val << std::endl;
Or equivalently,
std::cout<< static_cast<S*>(p)->val << std::endl;
[But also: the statement *(struct S*) p = s; technically has undefined behavior, even though all most implementations will allow it. This is because C++ has rules about when an object is created, and there was no object of type S previously at that address, and assignment does not create an object except for some cases involving union members. A similar statement that does not have this problem would be new(p) S{s};.
Also also: use of malloc or void* is usually not a good idea in C++ in the first place. malloc should only be used when interfacing with a C library that requires it. Anything for which void* seems useful can probably be done more safely using templates. In a few cases a void* might be the only way to do something or "cleverly" avoid code duplication or something, but still use it sparingly and always with extreme caution.]

How to modify the ostream object to create ideal cout?

I am using c++11 currently and I am working on a friend function to print out sth, but before calling the print function I need to call a member function inside the class to access and serialize the two data member. I am having a problem modifying the ostream object.
The code is as below:
friend ostream& operator<<(ostream& os, const Card& c) {
c.serialize(os);
return os;}
void NumberCard:: serialize(ostream& os) const
{
Color c=this->getColor();
switch(c){
case Color::red: os=(os<<"R"<<this->getPoint());break;
case Color::yellow: os=(os<<"Y"<<this->getPoint());break;
case Color::blue: os=(os<<"B"<<this->getPoint());break;
case Color::green: os=(os<<"G"<<this->getPoint());break;
default:break;}}
My current method doesn't work and the error is:
use of deleted function 'std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator=(const std::basic_ostream<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]'
It would be really appreciated if someone could give me some suggestions.
Don't use
os=(os<<"R"<<this->getPoint());
That is a problem since assignment to an ostream object is not supported by the standard library.
Use
os << "R" << this->getPoint();
ostream& os is a reference to an ostream. A C++ reference to an object is supposed to be indistinguishable from the actual object in terms of how it is used. This means that a reference cannot be reassigned -- rather, the object being referenced gets assigned to instead of the reference variable itself.
ostream is declared with a deleted copy-assignment operator, because you cannot copy a stream (this makes sense).
Combining these together, you'll understand that os = ... is causing the assignment operator to be called, which results in that error.
As it turns out, there's no need to reassign to os, since the reference returned by << is to the same (mutated) ostream object in the first place (this is done so that << calls can be chained).
Your switch code then simplifies to:
case Color::red: os << "R" << this->getPoint(); break;
case Color::yellow: os << "Y" << this->getPoint(); break;
// ...

Is it possible to write a generic function that distiguishes between an rvalue and an lvalue?

I am trying to learn rvalue references, as an exercise I tried to do answer the following.
Is it possible to write a function that can tell (at least at runtime, better if at compile time) if the passed value is a value (non reference), a rvalue or an lvalue? for a generic type? I want to extract as much information about the type as possible.
An alternative statement of the problem could be:
Can I have a typeid-like function that can tell as much as possible about the calling expression?, for example (and ideally) if the type is T, T&, T const&, or T&&.
Currently, for example, typeid drops some information about the type and one can do better (as in the example the const and non-const reference are distiguished). But how much better than typeid can one possibly do?
This is my best attempt so far. It can't distinguish between a rvalue and a "constant". First and second case in the example).
Maybe distiguishing case 1 and 2 is not possible in any circumstance? since both are ultimately rvalue? the the question is Even if both are rvalues can the two cases trigger different behavior?
In any case, it seems I overcomplicated the solution as I needed to resort to rvalue conditional casts, and ended up with this nasty code and not even 100% there.
#include<iostream>
#include<typeinfo>
template<class T>
void qualified_generic(T&& t){
std::clog << __PRETTY_FUNCTION__ << std::endl;
std::clog
<< typeid(t).name() // ok, it drops any qualification
<< (std::is_const<typename std::remove_reference<decltype(std::forward<T>(t))>::type>::value?" const":"") // seems to detect constness rigth
<< (std::is_lvalue_reference<decltype(std::forward<T>(t))>::value?"&":"")
<< (std::is_rvalue_reference<decltype(std::forward<T>(t))>::value?"&&":"") // cannot distiguish between passing a constant and an rvalue expression
<< std::endl
;
}
using namespace std;
int main(){
int a = 5;
int const b = 5;
qualified_generic(5); // prints "int&&", would plain "int" be more appropriate?
qualified_generic(a+1); // prints "int&&" ok
qualified_generic(a); // print "int&", ok
qualified_generic(b); // print "int const&", ok
}
Maybe the ultimate solution to distiguish between the cases will involve detecting a constexpr.
UPDATE: I found this talk by Scott Meyers where he claims that "The Standard sometimes requires typeid to give the 'wrong' answer". http://vimeo.com/97344493 about minute 44. I wonder if this is one of the cases.
UPDATE 2015: I revisited the problem using Boost TypeIndex and the result is still the same. For example using:
template<class T>
std::string qualified_generic(T&& t){
return boost::typeindex::type_id_with_cvr<decltype(t)>().pretty_name();
// or return boost::typeindex::type_id_with_cvr<T>().pretty_name();
// or return boost::typeindex::type_id_with_cvr<T&&>().pretty_name();
// or return boost::typeindex::type_id_with_cvr<T&>().pretty_name();
}
Still it is not possible to distinguish the type of 5 and a+1 in the above example.

const shared_ptr to shared_ptr

How can one convert a shared_ptr that points to a const object to a shared_ptr that points to a non-const object.
I am trying to do the following :
boost::shared_ptr<const A> Ckk(new A(4));
boost::shared_ptr<A> kk=const_cast< boost::shared_ptr<A> > Ckk;
But it does not work.
'boost::const_pointer_cast' will do what you're asking for, but the obligatory second half of the answer is that you probably shouldn't use it. 99% of the time when it seems like you need to cast away the const property of a variable, it means that you have a design flaw. Const is sometimes more than just window dressing and casting it away may lead to unexpected bugs.
Without knowing more details of your situation one can't say for certain. But no discussion of const-cast is complete without mentioning this fact.
use boost::const_pointer_cast, documentation.
the proper way should be this
boost::shared_ptr<A> kk (boost::const_pointer_cast<A>(Ckk));
std::const_cast_pointer makes a second managed pointer. After the cast you have a writable pointer and the original const-pointer. The pointee remains the same. The reference count has been increased by 1.
Note that const_cast is a builtin keyword, but const_pointer_cast is a template function in namespace std.
The writable pointer can then be used to change the value from under the shared_ptr<const T>. IMHO the writable pointer should only persist temporarily on the stack; otherwise there must be a design flaw.
I once wrote a small test program to make this clear to myself which I adapted for this thread:
#include <memory>
#include <iostream>
#include <cassert>
using namespace std;
typedef shared_ptr<int> int_ptr;
typedef shared_ptr<const int> const_int_ptr;
int main(void)
{
const_int_ptr Ckk(new int(1));
assert(Ckk.use_count() == 1);
cout << "Ckk = " << *Ckk << endl;
int_ptr kk = const_pointer_cast<int>(Ckk); // obtain a 2nd reference
*kk = 2; // change value under the const pointer
assert(Ckk.use_count() == 2);
cout << "Ckk = " << *Ckk << endl; // prints 3
}
Under UNIX or Windows/Cygwin, compile with
g++ -std=c++0x -lm const_pointer_cast.cpp

Resources