#include <iostream>
#include <vector>
using namespace std;
int main ()
{
vector <int> qwerty;
qwerty.push_back(5);
vector <int>* p = &qwerty;
cout << p[0]; //error: no match for 'operator<<' in 'std::cout << * p'
}
I'm generally unclear on how to use pointers with vectors, so I'm pretty mystified as to why this is not working. To my mind, this should print 5 to screen.
// either
cout << (*p)[0];
// or
cout << p->operator[](0);
Your 'cout' line is equivalent to:
cout << qwerty;
because p is a pointer to qwerty, which you then dereference with [0].
qwerty is a vector of type int, which can't be printed directly.
If you look at http://www.cplusplus.com/reference/stl/vector/ , you can see there is a class method for [] overload, so qwerty[0] would return an int.
So cout << qwerty[0]; would work.
To better understand what does "p[0]" mean, you can try the following statement:
cout << p[0][0];
this statement will enable you to print out "5" on the console. Because p[0] return the object reference "qwerty", then since vector object support index operation, you can use (p[0])[0] to get the first element in the vector.
Related
If I define a pointer to an object that defines the [] operator, is there a direct way to access this operator from a pointer?
For example, in the following code I can directly access Vec's member functions (such as empty()) by using the pointer's -> operator, but if I want to access the [] operator I need to first get a reference to the object and then call the operator.
#include <vector>
int main(int argc, char *argv[])
{
std::vector<int> Vec(1,1);
std::vector<int>* VecPtr = &Vec;
if(!VecPtr->empty()) // this is fine
return (*VecPtr)[0]; // is there some sort of ->[] operator I could use?
return 0;
}
I might very well be wrong, but it looks like doing (*VecPtr).empty() is less efficient than doing VecPtr->empty(). Which is why I was looking for an alternative to (*VecPtr)[].
You could do any of the following:
#include <vector>
int main () {
std::vector<int> v(1,1);
std::vector<int>* p = &v;
p->operator[](0);
(*p)[0];
p[0][0];
}
By the way, in the particular case of std::vector, you might also choose: p->at(0), even though it has a slightly different meaning.
return VecPtr->operator[](0);
...will do the trick. But really, the (*VecPtr)[0] form looks nicer, doesn't it?
(*VecPtr)[0] is perfectly OK, but you can use the at function if you want:
VecPtr->at(0);
Keep in mind that this (unlike operator[]) will throw an std::out_of_range exception if the index is not in range.
There's another way, you can use a reference to the object:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v = {7};
vector<int> *p = &v;
// Reference to the vector
vector<int> &r = *p;
cout << (*p)[0] << '\n'; // Prints 7
cout << r[0] << '\n'; // Prints 7
return 0;
}
This way, r is the same as v and you can substitute all occurrences of (*p) by r.
Caveat: This will only work if you won't modify the pointer (i.e. change which object it points to).
Consider the following:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v = {7};
vector<int> *p = &v;
// Reference to the vector
vector<int> &r = *p;
cout << (*p)[0] << '\n'; // Prints 7
cout << r[0] << '\n'; // Prints 7
// Caveat: When you change p, r is still the old *p (i.e. v)
vector<int> u = {3};
p = &u; // Doesn't change who r references
//r = u; // Wrong, see below why
cout << (*p)[0] << '\n'; // Prints 3
cout << r[0] << '\n'; // Prints 7
return 0;
}
r = u; is wrong because you can't change references:
This will modify the vector referenced by r (v)
instead of referencing another vector (u).
So, again, this only works if the pointer won't change while still using the reference.
The examples need C++11 only because of vector<int> ... = {...};
You can use it as VecPrt->operator [] ( 0 ), but I'm not sure you'll find it less obscure.
It is worth noting that in C++11 std::vector has a member function 'data' that returns a pointer to the underlying array (both const and non-const versions), allowing you to write the following:
VecPtr->data()[0];
This might be an alternative to
VecPtr->at(0);
which incurs a small runtime overhead, but more importantly it's use implies you aren't checking the index for validity before calling it, which is not true in your particular example.
See std::vector::data for more details.
People are advising you to use ->at(0) because of range checking. But here is my advise (with other point of view):
NEVER use ->at(0)! It is really slower. Would you sacrifice performance just because you are lazy enough to not check range by yourself? If so, you should not be programming in C++.
I think (*VecPtr)[0] is ok.
Consider the following program.
#include <iostream>
#include <vector>
void printEm(std::vector<size_t>* array){
std::cout << array[0] << "\n";
}
int main(){
std::vector<size_t> array;
return 0;
}
For some reason, whenever I compile this I get three pages worth or errors and I have no idea why. I think the type std::vector might be mismatching with what cout is expectng or something. Does anyone know how to fix this? I would post the error messages but they really go on forever. Thanks!
Your array parameter is a pointer, therefore you need to dereference it.
void printEm(std::vector<size_t>* array)
{
std::cout << (*array)[0] << "\n";
}
Or pass it by reference:
void printEm(std::vector<size_t>& array)
{
std::cout << array[0] << "\n";
}
Your passing array as a pointer so you need to dereference it before you use the [] operator. Try this:
(*array)[0];
As your code is right now you're trying to access element 0 of an array of std::vector<size_t> and print that.
array is a pointer to a vector, so array[0] is the vector itself, and you can't write a vector to a stream.
To get the first element you need (*array)[0].
Although much better would be to pass by (const) reference, where your existing code would just work:
void printEm(const std::vector<size_t> & array)
Hea everyone!
First of all, I am a completely new to C++ coming from a basic C background so it might be a little weird why I ask this.
The use scenario is that I want to change a map inside a different function by passing the map as a pointer to that function. Because I was reusing someone else's code, it was easier to assign the dereference to a variable instead of changing all of the references. This results in a similar case as this:
using namespace std;
typedef map<long, double> tl_t;
void fillmap(tl_t* m_p) {
tl_t m = *m_p;
m.insert(pair<long, double>(4, 3.0));
}
int main(int argc, char** argv) {
tl_t m;
cout << "Size: " << m.size() << "\n";
fillmap(&m);
cout << "Size: " << m.size() << "\n";
return 0;
}
The funny thing is that now both Size: strings return 0 and the original map m in the main function does not seem to be changed. This, however, works:
using namespace std;
typedef map<long, double> tl_t;
void fillmap(tl_t* m) {
(*m).insert(pair<long, double>(4, 3.0));
}
int main(int argc, char** argv) {
tl_t m;
cout << "Size: " << m.size() << "\n";
fillmap(&m);
cout << "Size: " << m.size() << "\n";
return 0;
}
As far as I can tell, these 2 cases should be working the same as both the reference of m in the main and fillmap function reference the same object. Of course the two m variables reside somewhere differently but should be referencing the same object.
As I am writing this, one thing that might be the problem is that variable m in main IS the map object while the variable m in fillmap TRIES to be the map object but can't because dereferencing the m_p pointer and assigning it to that last m doesn't actually make the last m a reference to the same object but actually copies it. Am I on the right track here?
And yes, I do know in normal use cases you should use a parameter reference in a similar situation, but this bugged the hell out of me :P.
Hopefully someone can enlighten me!
In C++ you have to add & to explicitly say that variable is reference.
In your example:
tl_t& m = *m_p;
should help.
If you use just "tl_t" you create local copy of the object which is destroyed once you leave fillmap function.
Example:
struct X {
int a,b;
}
Now types:
X - place in memory containing both a and b value.
X& - place in memory containing reference (const pointer) to the X.
X* - place in memory containing pointer to the X.
In both X and X& you can access fields of class using dot (xobject.a, xobject.b) but these are not same types.
It is because that
tl_t m = *m_p;
m will be construct by call the copy constructor, the copy process is by value. You just insert the pair<long, double>(4, 3.0) into m, not m_p
However,
(*m).insert(pair<long, double>(4, 3.0))
*m is the object you passed in by pointer, so, the pair<long, double>(4, 3.0) is inserted to *m itself.
class game_list
{
public:
string name;
};
game_list *pointer;
int main()
{
vector<game_list*> mainVector;
pointer=new game_list;
cin>>pointer->name;
mainVector.push_back(pointer);
cout << "Hello world!" << endl;
cout << mainVector[1];
return 0;
}
game_list is the class declaration. vector<game_list*> is the vector containing a bunch of game_list class pointers. I am trying to print the attributes of each game_list that inside the vector. So far I have tried, mainVector[1].name but seems like it doesn't work that way.Any suggestions?
You need to dereference the pointer, just like you did above.
cout << mainVector[1]->name;
or
cout << (*(mainVector[1])).name;
Oh, and ForEveR got it right, vector indices start at 0. To get first element, you can also use mainVector.front().
However, you probably don't want to use pointers at all. If you are sure you do, use boost::ptr_vector or a vector of std smart pointers. Right now this code has a memory leak.
Firstly - indexes start from zero, so mainVector[1] - is not correct.
Secondly - if you dereference your pointer mainVector[0]->name or (*mainVector[0]).name will give correct value.
From your code, you should be able to do:
cout << mainVector[0]->name << endl;
What is wrong with my code? I want to print out the array, but when I try to do so it seems to print out an address instead.
#include <iostream>
#include <ctime>
#include <stdlib.h>
using namespace std;
int main ()
{
srand(time(NULL));
int array[9]= {0};
for (int i=0;i<=8;i++)
{
array[i]= (rand()%101);
}
cout<< array;
system ("PAUSE");
return 0;
}
You can't just cout an array. Arrays are not cout-able. Whenever you successfully cout something of type T, it means that there's a dedicated overloaded << operator designed specifically to cout values of type T. And there's no dedicated << operator for cout-ing arrays (aside from strings). For this reason the compiler chooses the closest match for the given argument type: a << operator for pointers. Since arrays are convertible to pointers, that << is applicable here.
If you want to cout the values of all elements of your array, you'll have to either cout them manually, one by one, or use some standard algorithm that can do it for you. For example
std::copy(array, array + 9, std::ostream_iterator<int>(std::cout, " "));
You'll need to do a loop to output each array element on its own.
The problem is that C++ doesn't always know the size of the array, so it can't default to outputting the whole thing as you would expect.
You need to iterate over the array and print each element like how you assigned value at each index. Since array decays to a pointer to the first element in the sequence, you are getting the address.
std::cout doesn't have an overload for int array[9], so this decays to a pointer (int*) and this is what you'll see displayed (something like 0x7fffe47142d0).
To print the ints in the array individually, you will need to use a loop construct (like the for- loop you are using for populating the array) and send each of the ints to std::cout in turn, perhaps with some whitespace to format them.
Once you get the hang of C++ and its standard library, you may want to investigate how to do this with std::copy(), but I suspect this is a bit advanced for your homework.
C++ decays array type to a pointer type when the value is passed as argument to a function. C++11 has std::array (and TR1 specifies std::tr1::array) which retains the size of the array. Here is your example modified to use std::array:
#include <array>
#include <iostream>
#include <ctime>
#include <stdlib.h>
template<typename T, std::size_t N>
std::ostream& operator<< (std::ostream& ostm, const std::array<T, N>& a)
{
for (auto const& x : a)
ostm << x << ' ';
return ostm;
}
int main ()
{
srand(time(NULL));
std::array<int, 9> array;
for (auto& x : array)
x = rand() % 101;
std::cout<< array << std::endl;
}