• Advertisement
Sign in to follow this  

funtion problem?

This topic is 4048 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

hello, im trying to make a simple program to work with iterators and vectors, but i get a couple errors that i dont get. please help me out! thanx for any help :)
#include <iostream>
#include <iterator>
#include <string>
#include <vector>

void DislayGames(std::vector<std::string> games, std::vector<std::string>::iterator iter);
void AddGame(std::vector<std::string> games);
void RemoveGame(std::vector<std::string> games);

int main()
{
	// creates a vector to hold all the game titles
	std::vector<std::string> games;
	games.push_back("POOP");

	std::vector<std::string>::iterator iter;

	DisplayGames(games,iter);

	return 0;
}

void DisplayGames(std::vector<std::string> games, std::vector<std::string>::iterator iter)
{
	for(iter = games.begin(); iter != games.end(); iter++)
	{
		std::cout << *iter << std::endl;
	}
}
The error reads:
1>c:\documents and settings\brandon\my documents\visual studio 2005\projects\console apps\game list\main.cpp(27) : error C3861: 'DisplayGames': identifier not found

1>c:\documents and settings\brandon\my documents\visual studio 2005\projects\console apps\game list\main.cpp(33) : error C2365: 'DisplayGames' : redefinition; previous definition was 'formerly unknown identifier'

Share this post


Link to post
Share on other sites
Advertisement
That said:

- Simplify function interfaces. If a function can create one of its "arguments" locally in all cases (as a local variable), then it almost certainly should do so - it isn't really an argument. This is also in keeping with the general principle of restricting variable scope.

- Use typedefs.

- To avoid those problems with declarations, don't use them. Instead, put functions ahead of the first function that calls them (where possible). Function declarations are for header files.

- You don't need <iterator> to work with the iterators provided by a container. <iterator> contains special-purpose iterators (such as ostream_iterator) and iterator adapters (such as reverse_iterator).

- Pass function arguments of object type by const reference.

- Don't use std::endl as a '\n' substitute. Just flush at the end of each logical "block" of text.

- Use preincrement rather than postincrement with iterators.

Without introducing more useful tools ;), we get something like:


#include <iostream>
#include <string>
#include <vector>

typedef std::vector<std::string> gamelist;
typedef gamelist::iterator game_iterator;

void DisplayGames(const gamelist& games)
{
for (game_iterator iter = games.begin(); iter != games.end(); ++iter)
{
std::cout << *iter << '\n';
}
std::cout << std::endl;
}

int main()
{
gamelist games;
games.push_back("POOP");

DisplayGames(games);
}


Share this post


Link to post
Share on other sites
Thanks for the tips Zahlman :)

I got some questions for ya

1) why use preincreasment on iterators instead of postincreasment?

2) how much text should i wait for to use 'std::endl'?

Share this post


Link to post
Share on other sites
The postincrement (x++) syntax, in a loose way, means "give me the value of x, and once you have, increment x". The preincrement (++x) means "increment x, then give me the value".

In order to fulfill the requirements of the postincrement, the compiler basically does this:
temp = x;
x = x + 1;
// Do stuff with temp


When using an iterator (or any other object), this creates a hidden temporary object with the same value as the iterator. The result is that each time the iterator is incremented, there is a copy operation done as well to make the temporary value, which is wasteful. For certain types of objects, this copy can be a very expensive operation.

A preincrement does not preserve the old value, so it does not involve this copy overhead. This means that, in general, preincrement (and predecrement) operations are more efficient than postfix operations.



As for std::endl - the main thing to remember is that it sends a newline and flushes the output buffers. This flush operation is basically negligible if you're just doing simple console output. The only time you need to worry about the performance of the flush is when you are putting out a lot of data to a stream (this goes for both console and file streams, by the way).

The best thing to do is just use endl where you normally would, and if it becomes a performance concern, then consider only using "\r\n" and sending a flush (or endl) less often. If it isn't causing performance problems, don't worry about it.

Share this post


Link to post
Share on other sites
Why use \r\n? I thought any c++ output stream not opened in binary mode would do the conversion of \n -> \r\n for you (if required) so you could write your programs without worrying about the normal line ending of the system.

Share this post


Link to post
Share on other sites
Quote:
Original post by NUCLEAR RABBIT
Thanks for the tips Zahlman :)

I got some questions for ya
Zahlman will be able to give you better answers of course, but meanwhile:
Quote:
1) why use preincreasment on iterators instead of postincreasment?
Although 'increasement' is in fact a word (or so Google tells me), the correct term to use here is 'increment'.

As for preincrement vs. postincrement, these two operations have fundamentally different behaviors (which you may already know). With a postincrement you increment the value of the variable while retaining access to the value prior to the increment, e.g.:
int index = 4;
v[index++] = 0; // v[4] = 0
Conversely, preincrement has the following behavior:
int index = 4;
v[++index] = 0; // v[5] = 0;
You can see that, conceptually at least, the postincrement operator has to make a copy of the value of the variable, perform the increment, and then return the stored value, whereas the preincrement operator simply increments the value and then returns it (no copies).

Whether the 'extra work' done by the postincrement operator actually has an impact on performance depends on the circumstances, but IMO the most important reason to favor preincrement over postincrement in this context is that when programming, you should write what you mean. When you need access to the value of the variable prior to the increment, use postincrement; when you don't, use preincrement.
Quote:
2) how much text should i wait for to use 'std::endl'?
Here is an interesting article that addresses this very question (there's also a .pdf version if you prefer).

[Edit: ApochPiQ covered most of this.]

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
Why use \r\n? I thought any c++ output stream not opened in binary mode would do the conversion of \n -> \r\n for you (if required) so you could write your programs without worrying about the normal line ending of the system.


This is correct. I spent too long in C; the \r\n was just force of habit [smile]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement