24

通常の (弱い) 列挙がある場合、その列挙値を非型テンプレート パラメーターとして使用できます。次のようにします。

enum { Cat, Dog, Horse };

template <int Val, typename T> bool magic(T &t)
{
    return magical_traits<Val>::invoke(t);
}

そしてそれを次のように呼び出します:magic<Cat>(t)

私が見る限り、厳密に型指定された列挙型があり、列挙型をハードコーディングしたくない場合は、次のようになります。

enum class Animal { Cat, Dog, Horse };

template <typename EnumClass, EnumClass EnumVal, typename T> bool magic(T &t)
{
    return magical_traits<EnumVal>::invoke(t);
}

そして今、私は書く必要があります: magic<Animal, Animal::Cat>(t)、これは冗長に思えます。

列挙型クラスと値の両方を入力しないようにする方法はありますか?

#define MAGIC(E, T) (magic<decltype(E), E>(T));
4

4 に答える 4

26

C++17 を使用できる場合は、このようにすることができます

#include <type_traits>

enum class Animal { Cat, Dog, Horse };

template <typename EnumClass, EnumClass EnumVal> 
void magic_impl()
{
    static_assert(std::is_same_v<EnumClass, Animal>);
    static_assert(EnumVal == Animal::Cat);
}

template <auto EnumVal>
void magic()
{
    magic_impl<decltype(EnumVal), EnumVal>();
}

int main()
{
    magic<Animal::Cat>();
}

デモ: http://coliru.stacked-crooked.com/a/9ac5095e8434c9da

于 2017-11-25T09:30:55.667 に答える
12

すみません、それを言わなければなりません

それは不可能

マクロを取得し、恐ろしい名前のヘッダーに入れて、同僚のクリーンアップ スクリプトから保護します。最善の結果を期待します。

于 2012-02-22T18:28:27.537 に答える
4

の値のみに関心があり、enumその型には関心がない場合は、constexpr関数を使用して値を整数に変換し、型名を繰り返さないようにする必要があります。

enum class Animal { Cat, Dog, Horse };

template <typename T> constexpr int val(T t)
{
    return static_cast<int>(t);
}

template <int Val, typename T> bool magic(T &t)
{
    return magical_traits<Val>::invoke(t);
}

magic<val(Animal::Cat)>(t);

ただし、他の人がすでに指摘しているように、これもタイプに依存させたい場合は機能しません。

于 2012-02-22T19:05:49.983 に答える
2

この質問には受け入れられた回答があります(賛成)。

自分のコードをリファクタリングしているときに、より完全な解決策を見つけました。

ステップ1:私が書いていたコードを使用して:

template<typename V, typename EnumClass, EnumClass Discriminator>
class strong_type final // type-safe wrapper for input parameters
{
    V value;
public:
    constexpr explicit strong_type(V x): value{x} {}
    constexpr auto get() const { return value; }
};

ステップ 2: クライアント コード:

enum class color { red, green, blue, alpha };

// the part OP was asking about:
template<color C>
using color_channel = strong_type<std::uint8_t, color, C>;

using red = color_channel<color::red>; // single argument here
using green = color_channel<color::green>;
using blue = color_channel<color::blue>;
using alpha = color_channel<color::alpha>;
于 2017-11-25T08:52:54.410 に答える