10

using宣言は、列​​挙型では機能しないようです。

class Sample{
    public:
        enum Colour {RED, BLUE, GREEN};
}

using Sample::Colour;

動作しません!

列挙型の列挙子ごとにusing宣言を追加する必要がありますか? 以下のように:

using sample::Colour::RED;
4

4 に答える 4

10

クラスは名前空間を定義しないため、ここでは「使用」は適用されません。

また、列挙型を公開する必要があります。

同じクラス内で列挙型を使用しようとしている場合の例を次に示します。

class Sample {
 public:
  enum Colour { RED, BLUE, GREEN };

  void foo();
}

void Sample::foo() {
  Colour foo = RED;
}

クラス外からアクセスするには、次のようにします。

void bar() {
  Sample::Colour colour = Sample::RED;
}
于 2009-01-13T07:27:07.327 に答える
9

Steve Lacey's answerに追加するには、元のコードの問題は、メンバーを参照することですが、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 が指摘したように、enum 定義を名前空間に移動して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;
  }
};

問題はDerived::Colour、コンパイラ (14.6/2) によってオブジェクトとして扱われることです。

テンプレートの宣言または定義で使用され、テンプレート パラメーターに依存する名前は、該当する名前の検索で型名が検出されるか、名前がキーワード typename によって修飾されない限り、型を指定しないと見なされます。

名前が型になるための 2 つの条件を見ると、次のようになります。

  1. Colour依存するベースが検索されないため、ルックアップでタイプが見つかりませんSample<T>
  2. 名前は修飾されていません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;
  }
};

注: 1998 年版の標準ではtypename、using 宣言を使用することが許可されていなかったため、上記の修正は不可能でした。依存基底クラスからの型へのアクセスおよびCWG11を参照してください。

于 2009-01-13T11:43:05.143 に答える
5

C++ 標準、7.3.3.1:

using宣言で指定されたメンバー名は、using宣言が現れる宣言領域で宣言されます。[ 注: 指定された名前のみがそのように宣言されています。using-declaration で列挙名を指定しても、using-declaration の宣言領域でその列挙子が宣言されません。—終わりのメモ]

于 2009-01-13T07:28:42.847 に答える