using声明似乎不能与枚举类型一起使用:
class Sample{
public:
enum Colour {RED, BLUE, GREEN};
}
using Sample::Colour;
无法工作!
我们需要为枚举类型的每个枚举器添加一个using声明吗?就像下面这样:
using sample::Colour::RED;
using声明似乎不能与枚举类型一起使用:
class Sample{
public:
enum Colour {RED, BLUE, GREEN};
}
using Sample::Colour;
无法工作!
我们需要为枚举类型的每个枚举器添加一个using声明吗?就像下面这样:
using sample::Colour::RED;
补充Steve Lacey的答案,原始代码的问题在于您引用了一个成员,但using声明本身不是成员声明:
7.3.3/6规定:
类成员的using声明必须是成员声明。
为了强调这一点,以下示例可以正常工作:
class Sample
{
public:
enum Colour { RED,BLUE,GREEN};
};
class Derived : public Sample
{
public:
using Sample::Colour; // OK
};
最后,正如Igor Semenov所指出的那样,即使您将枚举定义移动到命名空间中,从而允许using声明,using声明也仅会将枚举类型的名称声明到命名空间中(2003标准参考为7.3.3/2)。
namespace Sample
{
enum Colour { RED,BLUE,GREEN};
}
using Sample::Colour;
using Sample::BLUE;
void foo ()
{
int j = BLUE; // OK
int i = RED; // ERROR
}
依赖基类型
为了允许部分和显式特化,当编译器解析类模板时,不会在依赖的基类中执行任何查找。因此,以下使用Sample作为模板的变体无法编译:
template <typename T>
class Sample
{
public:
enum Colour { RED,BLUE,GREEN};
};
template <typename T>
class Derived : public Sample<T>
{
public:
using Sample<T>::Colour; // What kind of entity is Colour?
Colour foo () // Not OK!
{
return this->RED;
}
};
查看名称成为类型的两个条件:在模板声明或定义中使用的名称,且依赖于模板参数,则假定该名称不是类型,除非适用的名称查找找到类型名称或名称由关键字typename限定。
template <typename T>
class Derived : public Sample<T>
{
public:
using typename Sample<T>::Colour; // Colour is treated as a typedef-name
Colour foo () // OK
{
return this->RED;
}
};
注意: 1998年版标准不允许在使用声明中使用typename
,因此上述修复方法不可行。请参见从依赖基类访问类型和CWG11。
template <typename T> class Sample
和template <typename T> class Derived:public Sample<T>
一起使用? - geometrian类不定义命名空间,因此“using”在这里不适用。
此外,您需要将枚举公开。
如果您正在尝试在同一类中使用枚举,以下是一个示例:
class Sample {
public:
enum Colour { RED, BLUE, GREEN };
void foo();
}
void Sample::foo() {
Colour foo = RED;
}
从类外部访问它的方式:
void bar() {
Sample::Colour colour = Sample::RED;
}
C++标准,7.3.3.1:
在using声明中指定的成员名称被声明在出现using声明的声明区域中。[注意:只有指定的名称被这样声明;在using声明中指定枚举名称不会在using声明的声明区域中声明其枚举器。 —注]
using enum
声明,从而最终允许直接访问枚举类的成员,就像这样(源代码):enum class fruit {
orange,
apple,
};
struct S {
using enum fruit; // OK, introduces orange and apple into S
};
void f() {
S s;
s.orange; // OK, names fruit::orange
S::orange; // OK, names fruit::orange
}
S
中,您也可以简单地使用orange
和apple
,而不是fruit::orange
和fruit::apple
。