使用变量来决定类或命名空间的类型

时间:2010-07-07 17:41:41

标签: c++ namespaces

好吧,所以我有明智的想法使用命名空间和if语句来改变变量的结果,在PHP中我想我可以使用连接但是c ++似乎没有连接到目前为止我可以看到。

有没有办法让这段代码生效?

namespace Blue
{

int seven = 7;
int eight = 8;


}

namespace Red
{

int seven = 1;
int eight = 2;

}

这里是主要的cpp文件

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;

7 个答案:

答案 0 :(得分:8)

您无法决定在运行时使用哪个命名空间。

这类事情只是编译时间。

答案 1 :(得分:2)

无法分配类或名称空间,并使namelookup的结果依赖于此。但是您可以分配变量的地址。所以在你的例子中,你可以说

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;

但是在这种情况下,您可以将print放入每个相应的if子句中,这对我来说更容易

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

如果经常访问,您可能希望将颜色放入单个数据结构

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

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

所以你可以使用索引,也许使用颜色名称的枚举而不是原始数字

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;
}

这样你也可以遍历颜色(使用数组的size()函数或其迭代器接口)。 array是TR1,C ++ 0x和Boost的一部分。

答案 2 :(得分:2)

否则不起作用,因为在编译时评估命名空间,并且直到运行时才知道A的内容。我的项目遇到了很多。我接口的一种语言在运行时已知动态类型,C ++使用编译时间分辨率进行输入。通常你会使用一个调用专门的模板化函数的case语句来解决这个问题。

    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;
    }

请注意,您无法执行类似

的操作
cout << Option<choice>::seven << endl

因为在编译时不知道选择的值。

他们喜欢这样看待:在编译时必须知道模板化参数中的任何内容,在运行时只知道的任何内容都需要进入case语句,然后调用正确模板化的函数。

请注意,这是一种非常复杂的方式来更改七和八的值,这可以通过另一种方式(例如,地图)更容易地完成,但有些情况下这非常有用。我一直这样做。

答案 3 :(得分:2)

我认为没有办法做到这一点,如果有的话,这可能是一个坏主意。您通常会使用多态来在C ++中完成此行为,例如:

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; }
};

然后:

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;

答案 4 :(得分:1)

&lt; EDIT&gt;这不解决命名空间问题,但是因为你提到了字符串连接...&lt; / EDIT&gt;

用C ++连接字符串:

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

我不确定你的问题代码中的代码是什么意思不起作用。您在不同的行上输出两个字符串(endl相当于"\n" +刷新流。)

修改

我认为问题是你正在尝试使用char数组。虽然这些技术上是字符串,但它们不是C ++的字符串方式。如果你想做像C这样的字符串,请使用C标准库strcat(或者最好是编译器可能附带的更安全的版本)。

答案 5 :(得分:1)

你不能直接在C ++中这样做。但是,您可以使用std :: map来获得类似的结果:

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

答案 6 :(得分:1)

在我看来,你并不真正关心你提出的问题,但我真的想知道,“名称空间有什么意义?”

命名空间主要用于分隔彼此具有相同名称的类(和其他数据元素)。

在C ++标准化之前,没有std :: string,但每个第三方库都拥有它。所以,如果你想要Widgetworks库用于某些事情,而CoolObjects库用于其他事情,那么如果你只是写了一个问题就会出现问题:

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

因为两者都会定义一个名为string的类。因此,标准化委员会意识到,如果他们添加了自己的string,现在你有三个。有解决方案是命名空间。标准字符串类(以及所有其他的strandard类)将位于名称空间std中,并且只会在您专门使用它时使用它。此外,您可以手动将旧的头文件包装到命名空间中以将其分离:

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

然后只使用你想要的作品:

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