tags:

views:

110

answers:

7

Alright, so i had the bright idea of using namespaces and an if statement to change the outcome of variables, in PHP i imagine i could've used concatenation however c++ doesnt seem to have concatenation as far as i can see so far.

so is there a way to get this code to work?

namespace Blue
{

int seven = 7;
int eight = 8;


}

namespace Red
{

int seven = 1;
int eight = 2;

}

and here is the main cpp file

int choice;

cin >> choice;

if(choice == 1)
{
    char A[] = "Blue";

}else if(choice == 2){

    char A[] = "Red";

}

cout << A::seven << endl;

cout << A::eight << endl;
+1  A: 

<EDIT>This doesn't address the namespace issue, but since you mentioned string concatenation...</EDIT>

To concatenate strings in C++:

string a = "Hello, ";
string b = "World!";
string c = a + b;

I'm not exactly sure what you mean by the code in your question not working. You're outputting the two strings on separate lines (endl is equivalent to "\n" + flushing the stream).

Edit

I think the problem is that you're trying to use char arrays. While these technically are strings, they aren't the C++ way of doing strings. If you want to do strings like C, use the C standard library strcat (or preferably the safer versions that likely come with your compiler).

Cogwheel - Matthew Orlando
He's trying to pick the namespace at runtime.
GMan
its because the A ive used as a variable are not reconized with the scope. which i knew would happen i just wanted to see if i was wrong. also thank you for the example.
TimothyTech
+1  A: 

You can't do that in C++ directly. However, you can use a std::map to achieve a similar result:

std::map<std::string, int> Blue;
Blue["seven"] = 7;
Blue["eight"] = 8;
assert(Blue["seven"] == 7);
zvrba
+8  A: 

You can't decide which namespace to use in runtime.

This sort of things is compile-time only.

Kotti
+1, right to the point. There's always conditional compilation as a (bad) alternative.
Justin Ardini
thanks that is what i wanted to know directly, so why would i ever want to use namespace when classes are so much cooler.
TimothyTech
@Timothy Very interesting opinion.
Kotti
@TimothyTech: Namespaces are used to organise classes by broad semantic relationships, for instance, user-interface classes might be in namespace `ui`, TimothyTech library classes might be in namespace `timtech`, and so on.
Jon Purdy
@Jon Purdy that makes alot of since thank you.
TimothyTech
+2  A: 

It's not possible to assign classes or namespaces and make the outcome of namelookup dependent on this. But you can assign the address of variables. So in your example, you could say

array<int*, 2> nums;    
if(choice == 1)
{
    array<int*, 2> blues = {{ &Blue::seven, &Blue::eight }};
    nums = blues;
} else if(choice == 2) {
    array<int*, 2> reds = {{ &Red::seven, &Red::eight }};
    nums = reds;
}

cout << *nums[0] << endl;
cout << *nums[1] << endl;

However in this case you can put the print into each respective if clause, which looks easier to me

if(choice == 1)
{
    cout << Blue::seven << endl;
    cout << Blue::eight << endl;
} else if(choice == 2) {
    cout << Red::seven << endl;
    cout << Red::eight << endl;
}

If you accesses are often, you may wish to put the colors into a single data-structure

typedef std::array<int, NumberCount> number_array;
typedef std::array<number_array, ColorCount> color_array;

color_array colors = {{ {{ 7, 8 }}, {{ 1, 2 }} }};

So you could use an index, maybe using enumerations for the color names instead of raw numbers

int arrayIndex = -1;
if(choice == 1)
{
    arrayIndex = 0;
} else if(choice == 2) {
    arrayIndex = 1;
}

if(arrayIndex != -1) {
    cout << colors[arrayIndex][0] << endl;
    cout << colors[arrayIndex][1] << endl;
}

This way you can also iterate over the colors (using array's size() function or its iterator interface). array is part of TR1, C++0x and Boost.

Johannes Schaub - litb
+2  A: 

No that won't work because the namespace is evaluated at compile time and the contents of A are not known until runtime. I run into this a lot with my projects. One of the languages I interface with has dynamic typing known at run time and C++ uses compile time resolution for the typing. Usually you get around this with a case statement that calls specialized templated functions.

    enum Choice
    {
        blue,
        red
    }

    template <Choice c>
    struct Option
    {
        enum {seven=0};
        enum {eight=0};
    };

    template <>
    struct Option<blue>
    {
        enum {seven=7};
        enum {eight=8};
    }

    template <>
    struct Option<red>
    {
        enum {seven=1};
        enum {eight=2};
    }

    ...

    switch (choice)
    {
    case red:
        cout << Option<red>::seven << endl;
        cout << Option<red>::eight << endl;
    case blue:
        cout << Option<blue>::seven << endl;
        cout << Option<blue>::eight << endl;
    }

note, that you can't do something like

cout << Option<choice>::seven << endl

because the value of choice isn't known at compile time.

They way I like to view it: anything that's in a templated argument has to be known at compile time, anything that's only known at run time needs to go in a case statement which then calls the properly templated function.

Note that this is a uber complicated way of changing the values of seven and eight, which could be done easier another way (say, a map), but there are cases where this is very useful. I do it all the time.

miked
+1  A: 

I don't think there is a way to do this, and if there were, it's probably a bad idea. You would normally accomplish this behavior in C++ using polymorphism, e.g.:

class Color {
  virtual int seven() = 0;
  virtual int eight() = 0;
};
class Blue : public Color {
  int seven() { return 7; }
  int eight() { return 8; }
};
class Red : public Color {
  int seven() { return 1; }
  int eight() { return 2; }
};

and then:

int choice;
Color* color;

cin << choice;
if (choice == 1)
  color = new Blue;
else
  color = new Red;

cout << color->seven() << endl;
cout << color->eight() << endl;

delete color;
KenE
that is normally how i would do it!, im trying to find out why the heck i would ever want to use a namespace. who cares about wanting two of the same named variables
TimothyTech
Nice one :) Personally, i didn't think about polymorphism at all :) Best add a virtual destructor for completion, and you get my +1
Johannes Schaub - litb
In that case, maybe you should just ask "Why the heck would I ever want to use a namespace in C++?" ;)
KenE
@TimothyTech- Namespaces are useful in many situations, don't write them off completely. This is simply not an instance where a namespace is useful. If you are writing libraries or highly modularized code, then namespaces can become more useful than they might seem from a relatively simple program like this one.
bta
@TimothyTech Say you are using a screen graphics library and a printing library, and they both have a class called `Color`. Wouldn't it be nice to be able to use `graphics::Color` and `printing::Color` instead of dealing with the headache of making sure both headers are never included at once?
Tyler McHenry
+1  A: 

It seems to me that you don't really care about the question you ask, but really want to know, "What's the point of namespaces?"

Namespace are used mainly to segrate class (and other data elements) whch have the same name from each other.

Back before C++ was standardized, there was no std::string, but every 3rd-party library had it's own. So, if you want to both Widgetworks library for some things, and CoolObjects library for other things, you'd have a problem if you merely wrote:

#include "widgetworx.h"
#include "coolobjects.h"

Because both would define a class called string. So the standardization committee realized that if they added their own string, now you'd have three. There solution was namespaces. The Standard string class (and all the other strandard classes) would be in namespace std, and it would only be used you specifically said to use it. Further, you could manually wrap the older header files into namespaces to seaprate them:

namespace WW
{
    #include "widgetworx.h"
}
namespace CO
{
    #include "coolobjects.h"
}

and then just use the piece that you want:

using CO::matrix;
using WW::complex;
using std::string;
James Curran