使用声明似乎不适用于枚举类型
class Sample{
public:
enum Colour { RED,BLUE,GREEN};
}
using Sample::Colour;
不起作用!! 我们是否需要为枚举类型的每个枚举器添加使用声明?如下所示
using sample::Colour::RED;
答案 0 :(得分:10)
类没有定义名称空间,因此“使用”在这里不适用。
另外,你需要公开枚举。
如果你试图在同一个班级中使用枚举,这里有一个例子:
class Sample {
public:
enum Colour { RED, BLUE, GREEN };
void foo();
}
void Sample::foo() {
Colour foo = RED;
}
并且无需课程即可访问它:
void bar() {
Sample::Colour colour = Sample::RED;
}
答案 1 :(得分:8)
要添加到Stevela的answer,原始代码的问题在于您引用成员,但using声明本身不是成员声明:
7.3.3 / 6有:
类成员的使用声明 应是会员声明。
要突出显示此内容,以下示例可以正常工作:
class Sample
{
public:
enum Colour { RED,BLUE,GREEN};
};
class Derived : public Sample
{
public:
using Sample::Colour; // OK
};
最后,正如Igor Semenov here指出的那样,即使将枚举定义移动到命名空间中,从而允许使用声明,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;
}
};
问题是编译器将Derived::Colour
视为对象(14.6 / 2):
模板声明或定义中使用的名称依赖于模板参数的名称,除非适用的名称查找找到类型名称或名称由关键字typename限定,否则不会命名类型。
查看名称为类型的两个条件:
Colour
找不到类型,因为未搜索从属基础Sample<T>
。typename
因此,该示例需要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;
}
};
注意:该标准的'98版本不允许typename
与using声明一起使用,因此无法进行上述修复。请参阅Accessing types from dependent base classes和CWG11。
答案 2 :(得分:5)
C ++标准,7.3.3.1:
a中指定的成员名称 using声明在声明中声明 声明区域中的 出现使用声明。 [ 注意: 只有指定的名称才是这样 声明;指定枚举 使用声明中的名称不会 在...中声明其枚举器 using-declaration的声明 区域。 - 后注]
答案 3 :(得分:0)
现在,有一个相关的问题:'using enum' in C++20。
C ++ 20似乎可以选择进行using enum
声明,从而最终允许直接访问枚举类的成员,例如(source):
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
。 / p>