29

名前空間に列挙型があり、別の名前空間にあるかのように使用したいと思います。直感的には、「using」または「typedef」を使用してこれを実現できると思いましたが、どちらも実際には機能しません。それを証明するコードスニペット。GCCとSunCCでテストされています。

namespace foo
{

enum bar {
    A
};

}

namespace buzz
{
// Which of these two methods I use doesn't matter,
// the results are the same.
using foo::bar;
//typedef foo::bar bar;
}

int main()
{
    foo::bar f; // works
    foo::bar g = foo::A; // works

    buzz::bar x; // works
    //buzz::bar y = buzz::A; // doesn't work
    buzz::bar z = foo::A;
}

問題は、列挙型自体はインポートされますが、その要素はインポートされないことです。残念ながら、他の多くの既存のコードを壊さずに、元の列挙型を変更して、追加のダミーの名前空間またはクラスに含めることはできません。私が考えることができる最善の解決策は、列挙型を手動で再現することです。

namespace buzz
{
enum bar
{
    A = foo::A
};
}

しかし、それはDRYの原則に違反しています。もっと良い方法はありますか?

4

5 に答える 5

27

ネストされた名前空間で既存の名前空間をラップし、それを元の名前空間で「使用」します。

namespace foo
{
    namespace bar_wrapper {
        enum bar {
            A
        };
    }
    using namespace bar_wrapper;
}

namespace buzz
{
    using namespace foo::bar_wrapper;
}
于 2010-07-20T19:12:39.370 に答える
10

私は Mark B のアプローチが一番好きですが、既存のコードを壊さないので、次のこともできます:

名前空間 foo {
 列挙バー {
  A、B [..]
 };
}

名前空間の話題 {
 foo::bar; の使用
 foo::A; の使用
 foo::B の使用;
 [..]
}
于 2010-07-20T19:32:00.903 に答える
6

ここでの問題は、using 宣言が値の名前ではなく、列挙型の名前のみを取得することです。 列挙型はスコープではなく、列挙子の名前を持ちません。列挙値自体をインポートすることはできないと思います。列挙型を構造体/名前空間にラップして使用してみてください。

于 2010-07-20T19:02:25.473 に答える
4

C++11から使えますenum class。インポートenum classすると、そのすべての値がインポートされます。

namespace foo
{

enum class bar {
    A
};

}

namespace buzz
{
using foo::bar;
}

int main()
{
    foo::bar f;
    foo::bar g = foo::bar::A;

    buzz::bar x;
    buzz::bar y = buzz::bar::A;
    buzz::bar z = foo::bar::A;
}

上記のコードは正常にコンパイルされます: http://coliru.stacked-crooked.com/a/2119348acb75d270

于 2018-03-01T09:02:26.523 に答える
1

本当にこれを行う必要がある場合は、using namespace foo;の代わりに試してくださいusing foo::bar;。ただし、列挙型をクラスまたは別の名前空間にカプセル化することをお勧めします。

于 2010-07-20T19:04:29.950 に答える