অবিচ্ছিন্ন এনাম সি ++ 11


17

এনাম যদি অবিচ্ছিন্ন থাকে তবে কি সি ++ 11 এ চেক করার কোনও উপায় আছে ?

এটি এনাম মানগুলি দেওয়া সম্পূর্ণরূপে বৈধ। এনাম কি অবিচ্ছিন্ন তা পরীক্ষা করার জন্য সি ++ 14, সি ++ 17 বা সি ++ 20 এ জাতীয় বৈশিষ্ট্যের মতো কোনও বৈশিষ্ট্য থাকতে পারে? এটি একটি স্ট্যাটিক_সেসারে ব্যবহৃত হবে।

একটি ছোট উদাহরণ অনুসরণ করে:

enum class Types_Discontinuous {
  A = 10,
  B = 1,
  C = 100
};

enum class Types_Continuous {
  A = 0,
  B = 1,
  C = 2
};

static_assert(SOME_TEST<Types_Discontinuous>::value, "Enum should be continuous"); // Fails
static_assert(SOME_TEST<Types_Continuous>::value, "Enum should be continuous");    // Passes

1
মানে অবিরত, এটির আরোহী ক্রম আছে বা এর অর্থ শূন্য দিয়ে শুরু হয় এবং তারপরে প্রতিটি মানের জন্য +1 হয়?
RoQuOTriX

5
অঙ্কের লেবেল গণনার কোনও উপায় নেই তাই এটি প্রোগ্রামের ভিতরে থেকেই করা সম্ভব নয়।
কিছু প্রোগ্রামার বাবু

1
মজাদার. আমি কীভাবে কোনও ফ্যাকটোরিয়াল গণনা করার জন্য একটি সংকলক পেতে পারি তার লাইন বরাবর টেমপ্লেট প্রোগ্রামিংয়ের লাইন ধরে ভাবছি। আপনি এ এবং সি দুটি সীমাটি দিয়ে জিনিসটি সরিয়ে ফেলবেন এবং টেমপ্লেট ফাংশনগুলি SFINAE এর মাধ্যমে তাদের মধ্যে থাকা সমস্ত মানগুলির উপস্থিতি বা অন্যথায় পরীক্ষা করে দেখুন enum। দুঃখের সাথে আমার একটি দিনের চাকরি আছে তাই এটি লেখার চেষ্টা করতে পারি না, যদিও আমি এই পদ্ধতির উপর ভিত্তি করে একটি উত্তরকে অগ্রাহ্য করব। আমি নিশ্চিত যে @ বারারি বা @ এসির মতো কেউ এটি করতে পারে।
বাথশেবা

1
@RoQuOTriX কীভাবে আপনি একটি লেবেলের সাথে একটি মান মেলে? এবং আপনি কীভাবে লেবেলের ক্রমটি পরীক্ষা করবেন? এবং এটি সংকলন সময়ে কীভাবে করা যেতে পারে (যার জন্য প্রয়োজন static_assert)? এমনকি যদি আপনি একটি "সুন্দর সমাধান" তৈরি করতে না পারেন তবে দয়া করে একটি উত্তর লিখুন কারণ আমি খুব আগ্রহী যে এটি কীভাবে জেনেরিক উপায়ে করা যায়।
কিছু প্রোগ্রামার বাবু

1
@ সোপমপ্রগ্রামারডুড আপনি যা বর্ণনা করেছেন তা হ'ল "সুন্দর" বা ভাল সমাধান। আমার অর্থ হ'ল "সহজ" চেক সমাধান, যা আপনাকে প্রত্যেক এনাম এবং god
শ্বরের

উত্তর:


7

বেশ কয়েকটি enumএর জন্য আপনি সম্ভবত ম্যাজিক এনুম লাইব্রেরিটি ব্যবহার করে এর মাধ্যমে হ্যাক করতে পারেন । উদাহরণ স্বরূপ:

#include "magic_enum.hpp"

template <typename Enum>
constexpr bool is_continuous(Enum = Enum{}) {
    // make sure we're actually testing an enum
    if constexpr (!std::is_enum_v<Enum>)
        return false;
    else {
        // get a sorted list of values in the enum
        const auto values = magic_enum::enum_values<Enum>();
        if (std::size(values) == 0)
            return true;

        // for every value, either it's the same as the last one or it's one larger
        auto prev = values[0];
        for (auto x : values) {
            auto next = static_cast<Enum>(magic_enum::enum_integer(prev) + 1);
            if (x != prev && x != next)
                return false;
            else
                prev = x;
        }
        return true;
    }
}

নোট করুন যে এটি লাইব্রেরির নাম থেকেই বোঝা যাচ্ছে, "যাদু" - পাঠাগারটি বেশ কয়েকটি সংকলক-নির্দিষ্ট হ্যাকগুলিতে কাজ করে। এর ফলে এটি আপনার "খাঁটি সি ++" এর প্রয়োজনীয়তাটি সত্যিই পূরণ করে না, তবে ভাষায় প্রতিবিম্বের সুযোগ না পাওয়া পর্যন্ত আমরা সম্ভবত এটি পেতে পারি।


এটি সত্যই যাদু তবে এটি আমার পরিস্থিতিকে সবচেয়ে ভাল মানাবে।
বার্ট

7

খাঁটি সি ++ এ এটি সম্ভব নয়, কারণ এনাম মানগুলি গণনা করার, বা মানগুলির সংখ্যা এবং সর্বনিম্ন এবং সর্বাধিক মানগুলি আবিষ্কার করার কোনও উপায় নেই। তবে আপনি যা চান তার কাছাকাছি কিছু বাস্তবায়নের জন্য আপনি আপনার সংকলকের সাহায্য ব্যবহার করে চেষ্টা করতে পারেন। উদাহরণস্বরূপ, জিসিসি-তে কোনও সংকলনের ত্রুটি কার্যকর করা সম্ভব হয় যদি কোনও switchবিবৃতি এনুমের সমস্ত মান হ্যান্ডেল করে না:

enum class my_enum {
    A = 0,
    B = 1,
    C = 2
};

#pragma GCC diagnostic push
#if __GNUC__ < 5
#pragma GCC diagnostic error "-Wswitch"
#else
#pragma GCC diagnostic error "-Wswitch-enum"
#endif

constexpr bool is_my_enum_continuous(my_enum t = my_enum())
{
    // Check that we know all enum values. Effectively works as a static assert.
    switch (t)
    {
    // Intentionally no default case.
    // The compiler will give an error if not all enum values are listed below.
    case my_enum::A:
    case my_enum::B:
    case my_enum::C:
        break;
    }

    // Check that the enum is continuous
    auto [min, max] = std::minmax({my_enum::A, my_enum::B, my_enum::C});
    return static_cast< int >(min) == 0 && static_cast< int >(max) == 2;
}

#pragma GCC diagnostic pop

স্পষ্টতই, এটি প্রদত্ত এনামের জন্য বিশেষায়িত, তবে এই জাতীয় ফাংশনগুলির সংজ্ঞা প্রিপ্রোসেসর দিয়ে স্বয়ংক্রিয় করা যেতে পারে।


আমি যদি সঠিকভাবে বুঝতে পারি তবে এর জন্য মিনম্যাক্সের জন্য স্যুইচ এবং তালিকার সমস্ত এনাম মানগুলি লিখতে হবে। বর্তমানে আমার একাধিক এনাম রয়েছে তাই এটি সত্যই সম্ভব তবে আমার পরিস্থিতির পক্ষে পছন্দ করা হয়নি।
বার্ট

1

আমি এই সম্পর্কে একটি উত্তর দেখতে চাই। আমারও এটির দরকার ছিল।

দুর্ভাগ্যক্রমে, আমি বিদ্যমান ইউটিলিটিগুলি ব্যবহার করে এটি সম্ভব বলে মনে করি না। আপনি যদি এটিতে কোনও ধরণের বৈশিষ্ট্য প্রয়োগ করতে চান তবে আপনার সংকলকের কাছ থেকে আপনার সমর্থন প্রয়োজন, সুতরাং এটির জন্য একটি টেমপ্লেট লিখতে পারা সম্ভব নয়।

আমি ইতিমধ্যে একটি নির্দিষ্ট ট্যাগ দিয়ে অঙ্কটি প্রসারিত করেছি এটি চিহ্নিত করার জন্য এবং এটি অবিলম্বে আপনাকে আকার দেবে: এনুম ক্লাস কনস্ট্রাক্টর সি ++, নির্দিষ্ট মান কীভাবে পাস করবেন?

বিকল্পভাবে, আপনি নিজের বৈশিষ্ট্য লিখতে পারেন:

 template<T> struct IsContiguous : std::false_type {};

আপনি যখনই এটি ব্যবহার করতে চান একটি সংগত এনাম সংজ্ঞায়িত করেন তখন এটিকে বিশেষীকরণ করা প্রয়োজন। দুর্ভাগ্যক্রমে, এনাম পরিবর্তিত হলে এটির কিছু রক্ষণাবেক্ষণ এবং মনোযোগ প্রয়োজন।


1
আপনি একটি কোড চেকার লিখতে পারেন, যা সংকলন করার সময় পরীক্ষা করে যদি টাইপটি সঠিকভাবে সেট করা থাকে
RoQuOTriX

হ্যাঁ, সত্যিই। আপনার যদি এটি লেখার ক্ষমতা থাকে।
জেভিআপন

1

সমস্ত এনামগুলি অবিচ্ছিন্ন। 0 সর্বদা অনুমোদিত; অনুমোদিত সর্বোচ্চ মান হ'ল পরের 1<<N -1(সমস্ত বিট একটি) পর্যন্ত সর্বোচ্চ গোলাকার এবং এর মধ্যে থাকা সমস্ত মানকেও অনুমোদিত। ([dcl.enum] 9.7.1 / 5)। যদি সেখানে নেতিবাচক গণক সংজ্ঞায়িত হয় তবে অনুমোদিত সর্বনিম্ন মানটি একইভাবে সর্বনিম্ন গণকের দ্বারা বৃত্তাকার দ্বারা সংজ্ঞায়িত করা হয়।

এর মধ্যে সংজ্ঞায়িত গণকগুলি হ'ল enumমান এবং সঠিক ধরণের মান সহ ধ্রুবক অভিব্যক্তি, তবে আপনি enumএকই বৈশিষ্ট্যগুলির বাইরে অতিরিক্ত ধ্রুবককে সংজ্ঞায়িত করতে পারেন :

constexpr enum class Types_Discontinuous = static_cast<Types_Discontinuous>(2)


2
যদিও আপনি সঠিক, এটি ওপি থেকে পরিষ্কার যে আমরা এটি নির্ধারিত মানগুলির জন্য জানতে চাই। (পিএস: ডাউন ভোট আমার নয়)
জেভিআপন

1
@ জেভিএপেন: এটাই সঠিক সমস্যা। "সংজ্ঞায়িত মানগুলি" এনাম টাইপের নিজস্ব সম্পত্তি নয়। এনামের মানগুলি কী কী তা মান স্পষ্ট licit
এমসাল্টারস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.