9

これはできますか?

enum A
{
    enum B
    {
        SOMETHING1,
        SOMETHING2
    };

    enum C
    {
        SOMETHING3,
        SOMETHING4
    };
};

そうでない場合、代替ソリューションはありますか?

この質問の目的: 次のようなことができるようになりたい/必要があります:

enum class ElementaryParticleTypes
{

    enum class MATTER
    {
        enum class MESONS
        {
            PI
        };

        enum class BARYONS
        {
            PROTON,
            NEUTRON
        };

        enum class LEPTONS
        {
            ELECTRON
        };
    };

    enum class ANTI_MATTER
    {
        enum class ANTI_MESONS
        {
            ANTI_PI
        };

        enum class ANTI_BARYONS
        {
            ANTI_PROTON
            ANTI_NEUTRON
        };

        enum class ANTI_LEPTONS
        {
            POSITRON
        };
    };

};

強く型付けされた機能を使用したい。

4

4 に答える 4

15

いいえ、そのようにネストすることはできません。実際、どのコンパイラもそれを拒否します。

そうでない場合、代替ソリューションはありますか?

それは主に、何を達成しようとしているのかによって異なります (どの問題の解決策ですか?)。のようなものを記述できるようにすることが目標の場合は、次のようA::B::SOMETHING1に名前空間内で定義できます。

namespace A
{
    enum B
    {
        SOMETHING1,
        SOMETHING2
    };

    enum C
    {
        SOMETHING3,
        SOMETHING4
    };     
}
于 2013-02-24T22:02:20.150 に答える
3

この特定のケースでは、列挙が頻繁に変更される可能性は低いため、次のようにすることができます。

namespace ParticleTypes {
    namespace Matter {
        enum Mesons {
            Pi
        };

        enum Baryons {
            Proton = Pi + 1,
            Neutron
        };

        enum Leptons {
            Electron = Neutron + 1
        };
    }

    namespace AntiMatter {
        enum AntiMesons {
            AntiPi = Matter::Electron + 1
        };

        // ...
    }
}

しかし、なぜenum異なるタイプのパーティクルに対して異なるタイプが必要なのか疑問に思います。Mesonstype の引数を受け入れるが、 type の引数を受け入れない関数はありますLeptonsか? そうでない場合、およびすべての関数が任意の粒子を受け入れる場合は、単一のを使用し、できれば、などenumの値の名前に長いプレフィックスをドロップします。MATTER_MESONS_MATTER_BARYONS_

于 2013-02-24T23:13:20.503 に答える
0
MESONS pi = PI();
MATTER mat = pi;
assert (pi == mat);

ちょっとした C++11 のテンプレート マジックが気になりませんか?

template <typename T, typename... L>
struct is_defined_in : std::false_type {};

template <typename T, typename U, typename... L>
struct is_defined_in<T, U, L...> : is_defined_in<T, L...> {};

template <typename T, typename... L>
struct is_defined_in<T, T, L...> : std::true_type {};

template <int ID> struct helper {
  friend bool operator==(helper a, helper b)
  { return a.id == b.id; }
  friend bool operator!=(helper a, helper b)
  { return a.id != b.id; }

  int id=ID;
};
template <typename... B> struct category {
  int id;

  template <typename T,
            typename = typename std::enable_if<is_defined_in<T, B...>::value>::type>
  category(T t) : id(t.id) {}

  friend bool operator==(category a, category b)
  { return a.id == b.id; }
  friend bool operator!=(category a, category b)
  { return a.id != b.id; }
};

enum class ElementaryParticleTypesID
{ PI, PROTON, NEUTRON, ELECTRON };

struct PI       : helper<(int)ElementaryParticleTypesID::PI> {};
struct PROTON   : helper<(int)ElementaryParticleTypesID::PROTON> {};
struct NEUTRON  : helper<(int)ElementaryParticleTypesID::NEUTRON> {};
struct ELECTRON : helper<(int)ElementaryParticleTypesID::ELECTRON> {};

using MESONS = category<PI>;
using BARYONS = category<PROTON, NEUTRON>;
using LEPTONS = category<ELECTRON>;

using MATTER = category<MESONS, BARYONS, LEPTONS>;

(the static_assert現在、2 つの階層を超えると機能しませんが、必要に応じて追加できます)

于 2013-02-24T22:38:33.623 に答える
-4

いいえ、1 つの列挙内の長いリストですべてを定義しない限り、これを行う方法はありません。

enum class A{
  PARTICLE_MATTER_BARYON_PROTON,
  PARTICLE_MATTER_BARYON_NEUTRON,
  PARTICLE_ANTIMATTER_BARYON_PROTON // etc
};

これが理解できなければ、あなたは間違いなく物理学者です。

回答を受け入れるように求めるスタックオーバーフローからの通知を停止するための回答として、これを受け入れています。

于 2013-02-24T22:33:55.620 に答える