Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在C+中“使用”弱枚举+;11?_C++_C++11_Enums_Using - Fatal编程技术网

C++ 如何在C+中“使用”弱枚举+;11?

C++ 如何在C+中“使用”弱枚举+;11?,c++,c++11,enums,using,C++,C++11,Enums,Using,我在标题中的类中有枚举定义: namespace A { class B { public: enum Value { VALUE1 = 1, VALUE2 = 2, }; }; } 我想在没有前缀的源文件中使用它的值,如下所示: #include "header" int main() { someFn(VALUE1); return 0; } 我尝试使用A::B::Value来但clang给出了一个错误: 使用声明不能引用类成员 即使我将枚举移

我在标题中的类中有枚举定义:

namespace A {

class B {
 public:
  enum Value {
    VALUE1 = 1,
    VALUE2 = 2,
  };
};

}
我想在没有前缀的源文件中使用它的值,如下所示:

#include "header"

int main() {
  someFn(VALUE1);

  return 0;
}
我尝试使用A::B::Value来
但clang给出了一个错误:

使用声明不能引用类成员


即使我将枚举移到类之外:

namespace A {

enum Value {
  VALUE1 = 1,
  VALUE2 = 2,
};    

}
并使用::值执行
,错误消失,但编译器抱怨
VALUE1

使用未声明的标识符“VALUE1”

如果枚举是在其他地方定义的,是否有方法使用不带任何前缀的枚举值使用
#define
s是毫无疑问的


如果没有办法,那么在C++标准中实现这种行为可能是什么问题?

简单地说:不可能,因为EnUM在类中定义。

如果将
类B
更改为
命名空间B

namespace A {

namespace B {
  enum Value {
    VALUE1 = 1,
    VALUE2 = 2,
  };
};

}
然后就可以(正如您在代码中所写的那样):


枚举的处理方式类似于类。将其视为尝试执行以下操作:

class Value
{
public:
    static const int VALUE1 = 0;
};

using Value::VALUE1; // ERROR class-qualified name

简言之:您不能使用
语句以这种方式使枚举值可见。

我能想到的最接近的是:

namespace A {
  class B {
  public:
    enum Value { VALUE1 = 1, VALUE2 = 2 };
  };
};

const A::B::Value VALUE1 = A::B::VALUE1;

int main () {
  return VALUE1;
}

但它相当乏味,容易出错,绝对不值得

您的方法失败的原因有两个:

  • 第一个原因已由Bћ描述:不能在命名空间范围中引入嵌套类型的名称,请参见[namespace.udecl]/8

  • 当您使用A::B::Value编写
    ,当前范围中将只引入
    枚举
    本身的名称,而不是所有枚举数的名称。这样可以实现以下功能:

    namespace Values { enum Value{ VALUE1, VALUE2 }; }
    using Values::Value;  // don't pollute my scope with the enumerators
    
    Value v = Values::VALUE1;
    
  • 第二个问题可以通过单独引入枚举数来解决:

    namespace A
    {
        namespace B
        {
            enum Value
            {
                  VALUE1
                , VALUE2
            };
        }
    }
    
    int main()
    {
        using A::B::Value;
        using A::B::VALUE1;
        using A::B::VALUE2;
    
        Value v = VALUE1;
        v = VALUE2;
    }
    
    或者,正如建议的那样,您可以使用using指令引入命名空间的所有名称:

    namespace A
    {
        namespace B
        {
            enum Value
            {
                  VALUE1
                , VALUE2
            };
        }
    }
    
    int main()
    {
        using namespace A::B;
    
        Value v = VALUE1;
        v = VALUE2;
    }
    

    但是,正如我提到的,编译器(clang)给出了一个错误:
    使用未声明的标识符“VALUE1”
    @abyss.7这很奇怪。你应该得到“error:'A::B'不是命名空间”@abyss.7实际上,它告诉你我在答案中写了什么。我写的错误消息来自g++。即使错误消息不同,这对我们两人来说仍然不起作用。@Abysis.7在你的问题中,你写了“并使用::Value;
    ,”不要这样做。不要只导入
    名称。导入整个名称空间,并确保该名称空间仅用于该一个枚举。这不是一个好方法,因为我必须将所有枚举值复制到我要使用它们的地方。
    namespace A
    {
        namespace B
        {
            enum Value
            {
                  VALUE1
                , VALUE2
            };
        }
    }
    
    int main()
    {
        using namespace A::B;
    
        Value v = VALUE1;
        v = VALUE2;
    }