3

These second line of these is throwing this error, but I'm not sure why.

std::vector<std::string> weapons(100);
weapons[3] = "Rusty dagger";

--

Here's my entire file:

//global variables
#ifndef _GLOBAL_
#define _GLOBAL_

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

//prototypes
void NPCTalk(std::string const& speaker,std::vector<std::string> const& text);
void wait(double seconds);
void regionChange(int amount);
int getPositionInStringVector(std::vector<std::string> const& vec,std::string value);

//variables
std::vector<std::string> weapons(100);
weapons[3] = "Rusty dagger";

//defines
#define RegionChange 3

#endif //__GLOBAL__
pighead10
  • 4,155
  • 10
  • 34
  • 52

3 Answers3

12
weapons[3] = "Rusty dagger";

This is a statement. You can't write statements in global scope. You must put it inside a function.

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
  • Oh, okay. Would a initialise() function be advisable? I'm new to C++ and still getting used to the conventions. – pighead10 Mar 25 '11 at 19:44
  • 2
    This is not strictly true. You can do assignments at the top level as long as they are 'initializations'. The OPs assignment is not an initialization, just a straight ordinary assignment. – Omnifarious Mar 25 '11 at 19:44
  • 2
    @Pig Head: better to avoid global variables. – Yakov Galka Mar 25 '11 at 19:45
  • @Pig Head: You can initialize the vector as part of a definition, though that should go in a `.cpp` file, and it will require that you first initialize an ordinary C array of `const char *` and then feed pointers to array elements to the `vector` constructor. Though, really, as @ybungalobill points out, avoiding global variables is the wisest course. – Omnifarious Mar 25 '11 at 19:46
  • @Omnifarious: Nope. technically the assignments at the top level are *simple-declarations*. – Yakov Galka Mar 25 '11 at 19:46
  • @ybunga - It would be impractical to avoid global variables here. @Omnifarious - I think I'll just use an initialise() function. – pighead10 Mar 25 '11 at 19:47
  • 1
    @Pig: sorry, but the only place where it's impractical is in embedded systems. I doubt that it's your case. – Yakov Galka Mar 25 '11 at 19:50
3
weapons[3] = "Rusty dagger";

is a statement. It cannot appear outside of a function.

Instead, you could put it near the start of main(), or in some init_weapons() function which gets called early in your program.

aschepler
  • 70,891
  • 9
  • 107
  • 161
3

While calling an initialization function is one way to handle your problem, I thought an alternative might be in order. Here is something you can do in a .cpp file someplace:

static const char * const init_ary[] = {
   "Fred",
   "Barney",
   "Joe"
};

::std::vector< ::std::string> names(init_ary, init_ary+3);

Then you would have this declaration in your .h file:

extern ::std::vector< ::std::string> names;

But really, avoiding global variables is the best idea. They are seriously bad news for a whole host of reasons, some not immediately obvious. For example, they make your code tons harder to test.

Its well worth the seeming hit to an 'elegant' design to just pass around the variable to each and every function in order to avoid having them. In fact, if you start coding that up, I bet you start seeing patterns that cause you to rethink parts of your design and you'll end up with something even nicer and more actually elegant than the false 'elegance' you get from the global variable based design.

Omnifarious
  • 54,333
  • 19
  • 131
  • 194
  • What what be the next practical way of having something that can be accessed by everything without global variables? A 'global' class? – pighead10 Mar 25 '11 at 19:57
  • @Pig: think about what exact parts of your program need this array and pass it to them. Create something like `WeaponManager` that is responsible for weapons, and pass it as an argument to every component that needs to deal with weapons... – Yakov Galka Mar 25 '11 at 20:01
  • I've passed around a lot of variables to all my main functions, but why would that be better than a simple global variable? – pighead10 Mar 25 '11 at 20:01
  • 1
    @Pig Head: Pass it as a parameter to everything that needs it. Seriously. As I said, if you start doing that, you'll likely start seeing patterns that suggest a better design to you that is still not global variable based. You can simplify this some by passing it as an argument to some constructors and have the constructed class save a reference to it so it's sort of 'global' to that instance of the class. – Omnifarious Mar 25 '11 at 20:02
  • 1
    @Pig Head: Because, when time comes to test, you can pass whatever the heck you want to whatever it is that wants the data. This makes it much easier to test components in isolation from each other. This also makes it easier to write tests to make sure your program is not depending on some subtle feature like exactly how many items you have in your global array or that a 'Rusty dagger' is always found at position 3. – Omnifarious Mar 25 '11 at 20:05