سؤال

إذا كان لدي تعداد عادي (ضعيف)، فيمكنني استخدام قيمه التعدادية كمعلمات قالب غير نوع، كما يلي:

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));
هل كانت مفيدة؟

المحلول

يمكنك القيام بذلك بهذه الطريقة، إذا كنت تستطيع استخدام 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

نصائح أخرى

أنا آسف، يجب أن أقول لك ذلك

ليس من الممكن

خذ الماكرو، وضعه في رأس مسمى مخيف وقم بحمايته من البرنامج النصي للتنظيف الخاص بزميلك.نأمل للأفضل.

إذا كنت مهتمًا فقط بـ 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);

ومع ذلك، كما أشار الآخرون بالفعل، إذا كنت تريد جعل هذا يعتمد على النوع أيضًا، فلن ينجح الأمر.

هذا السؤال لديه إجابة مقبولة (تم التصويت عليه).

أثناء إعادة بناء الكود الخاص بي، توصلت إلى حل أكثر اكتمالاً:

الخطوة 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>;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top