ভেক্টরের বিকল্প <বিউল>


92

যেমন (আশাবাদী) আমরা সবাই জানি, vector<bool>সম্পূর্ণরূপে নষ্ট হয়ে গেছে এবং সি অ্যারে হিসাবে চিকিত্সা করা যায় না। এই কার্যকারিতাটি পাওয়ার সবচেয়ে ভাল উপায় কী? এখনও অবধি, আমি যে ধারণাগুলি ভেবেছি তা হ'ল:

  • vector<char>পরিবর্তে ব্যবহার করুন , বা
  • একটি মোড়ক ক্লাস ব্যবহার করুন এবং আছে vector<bool_wrapper>

আপনি ছেলেরা কীভাবে এই সমস্যাটি পরিচালনা করবেন? আমার c_array()কার্যকারিতা দরকার ।

একটি পার্শ্ব প্রশ্ন হিসাবে, আমার যদি c_array()পদ্ধতিটির প্রয়োজন না হয় তবে আমার এলোমেলো অ্যাক্সেসের প্রয়োজন হলে এই সমস্যাটির কাছে যাওয়ার সর্বোত্তম উপায় কী? আমি একটি deque বা অন্য কিছু ব্যবহার করা উচিত?

সম্পাদনা করুন:

  • আমার ডায়নামিক সাইজিং দরকার।
  • যারা জানেন না তাদের vector<bool>জন্য বিশেষায়িত করা হয়েছে যাতে প্রতিটি bool1 বিট নেয়। সুতরাং আপনি এটিকে সি-স্টাইলের অ্যারেতে রূপান্তর করতে পারবেন না।
  • আমার ধারণা "র‌্যাপার" হ'ল কিছুটা মিসনোমার। আমি এই জাতীয় কিছু ভাবছিলাম:

অবশ্যই, তারপরে আমাকে my_boolসম্ভাব্য সারিবদ্ধ সমস্যার কারণে পড়তে হবে :(

struct my_bool
{
    bool the_bool;
};
vector<my_bool> haha_i_tricked_you;

4
সি-স্টাইল অ্যারে ব্যবহার না করার কিছু কারণ আছে?
kquinn

rlbond, আপনার গতিশীল আকার প্রয়োজন?
জোহানেস স্কাউব -

16
ঠিক আছে আমি কামড় দেব - আপনি কেন ভেক্টরটিকে "" সম্পূর্ণরূপে ভাঙ্গা "বলে মনে করেন?
অ্যান্ড্রু গ্রান্ট


4
মজার বিষয় হল, vector<bool>আমার কোডটিতে কেবল একটি ডেটা রেস বাগ তৈরি করেছে, যেহেতু আমি প্রত্যাশা করেছি যে বিভিন্ন থ্রেড একই সাথে ভেক্টরের বিভিন্ন উপাদানগুলিকে একই সাথে নিরাপদে পরিবর্তন করতে সক্ষম হবে। ব্যবহার করে সমাধান করা deque<bool>
আন্দ্রেস রিওফ্রিও

উত্তর:



21

এটি একটি আকর্ষণীয় সমস্যা।

আপনার যদি প্রয়োজন হয় তবে std :: ভেক্টরটি কী ছিল যদি এটি বিশেষীকরণ না করা হত, তবে সম্ভবত এর মতো কিছু আপনার ক্ষেত্রে ভাল কাজ করবে:

#include <vector>
#include <iostream> 
#include <algorithm>

class Bool
{
public:

    Bool(): m_value(){}
    Bool( bool value ) : m_value(value){}

    operator bool() const { return m_value; }

    // the following operators are to allow bool* b = &v[0]; (v is a vector here).
    bool* operator& () { return &m_value; }
    const bool* operator& () const { return &m_value; }

private:

    bool m_value;

};




int main()
{
    std::vector<Bool> working_solution(10, false);


    working_solution[5] = true;
    working_solution[7] = true;


    for( int i = 0; i < working_solution.size(); ++i )
    {
        std::cout<< "Id " << i << " = " << working_solution[i] << "(" <<(working_solution[i] ? "true" : "false") << ")" <<std::endl; // i used ? : to be sure the boolean evaluation is correct
    }

    std::sort( working_solution.begin(), working_solution.end());
    std::cout<< "--- SORTED! ---" << std::endl;

    for( int i = 0; i < working_solution.size(); ++i )
    {
            bool* b = &working_solution[i]; // this works!

        std::cout<< "Id " << i << " = " << working_solution[i] << "(" << (working_solution[i] ? "true" : "false") << ")" <<std::endl; // i used ? : to be sure the boolean evaluation is correct
    }

    std::cin.get();
    return 0;
}

আমি ভিসি 9 দিয়ে এটি চেষ্টা করেছি এবং মনে হচ্ছে এটি ঠিক আছে। বুল শ্রেণীর ধারণা হ'ল একই আচরণ এবং আকার সরবরাহ করে (তবে একই ধরণের নয়) সরবরাহ করে বুল ধরণের অনুকরণ করা। এখানে প্রায় সমস্ত কাজ বুল অপারেটর এবং ডিফল্ট অনুলিপি নির্মাণকারীদের দ্বারা সম্পন্ন হয়। অ্যালগোরিদম ব্যবহার করার সময় এটি ধরে নেওয়া হিসাবে এটি প্রতিক্রিয়া হয় তা নিশ্চিত হওয়ার জন্য আমি একটি বাছাই যুক্ত করেছি।

নিশ্চিত নয় যে এটি সমস্ত ক্ষেত্রে উপযুক্ত হবে। যদি এটি আপনার প্রয়োজনের জন্য সঠিক হয় তবে এটি কোনও ভেক্টর-এর মতো শ্রেণীর লেখার চেয়ে কম কাজ হবে ...


"আমরা বুল * অপারেটর এবং () {রিটার্ন & এম_ভ্যালু;}" - এরর যোগ করতে পারি। আইএসও : " sizeof(bool)হওয়ার দরকার নেই 1"
এভজেনি প্যানাসিয়ুক

4
আমি কেবল পরিবর্তন করতে চান operator bool() constএকটি থেকে operator bool&()। এটি এটিকে একটি সরল বলের আচরণকে আরও ভালভাবে আয়না করে তোলে কারণ এটি কার্যাদি ইত্যাদির ক্ষেত্রে সমর্থন v[0] = true;করে?
এজেন্টলাইন

19

আপনার প্রয়োজনের উপর নির্ভর করে। আমি উভয় জন্য যেতে হবে std::vector<unsigned char>। আপনি কেবল কার্যকারিতার একটি উপসেট ব্যবহার করেন তবে একটি মোড়ক লেখা ভাল হতে পারে অন্যথায় এটি স্বপ্নদোষ হয়ে উঠবে।


unsigned charসর্বদা একটি একক বাইট হয় যদিও uint8_tএটি বাস্তবায়নের দ্বারা সমর্থিত হয় না। uint_fast8_tযদিও যদি অভিপ্রায় এটা পরিষ্কার এটি একটি একক বাইট এবং না একটি চরিত্র করা হয় কাজ করতে পারে, কিন্তু আপনি ভাল হিসাবে ব্যবহার হতে পারে std::byteতারপর
গ্যাব্রিয়েল রাভিয়ার

13

আপনি ছেলেরা কীভাবে এই সমস্যাটি পরিচালনা করবেন? আমার সি_রে () কার্যকারিতা দরকার।

boost::container::vector<bool>:

ভেক্টর < বিউল > বিশেষায়িতকরণ বেশ সমস্যাযুক্ত হয়েছে এবং মান থেকে এটি হ্রাস বা অপসারণ করার জন্য বেশ কয়েকটি ব্যর্থ চেষ্টা করা হয়েছে। Boost.Containerউচ্চতর বুস্ট.ডাইনামিক বিটসেট সমাধান রয়েছে বলে এটি প্রয়োগ করে না ।

...

সুতরাং বুস্ট :: কনটেইনার :: ভেক্টর :: ইটারেটর রিয়েল বুল রেফারেন্সগুলি ফিরিয়ে দেয় এবং সম্পূর্ণ কমপ্লায়েন্ট পাত্রে হিসাবে কাজ করে। তোমাদের মধ্যে একটি মেমরি অপ্টিমাইজ সংস্করণ প্রয়োজন বুস্ট :: ধারক :: ভেক্টর < bool, > বৈশিষ্ট্য, ব্যবহার করুন Boost.DynamicBitset


6

একটি ভেক্টর <int> ব্যবহার বিবেচনা করুন। আপনি অতীত সংকলন এবং টাইপ চেকিং পেয়ে গেলে, বুল এবং ইনট উভয়ই কেবল মেশিন শব্দ (সম্পাদনা: দৃশ্যত এটি সর্বদা সত্য নয়; তবে অনেকগুলি পিসি আর্কিটেকচারে সত্য হবে)। যেসব পরিস্থিতিতে আপনি কোনও সতর্কতা ছাড়াই রূপান্তর করতে চান সেখানে "বুল ফু = !! বার" ব্যবহার করুন, যা শূন্যকে মিথ্যা এবং অ-শূন্যকে সত্যে রূপান্তর করে।

কোনও ভেক্টর <চর> বা অনুরূপ স্থান কম ব্যবহার করবে, যদিও এটি কিছু পরিস্থিতিতে একটি (খুব ছোট) গতি হিট নেওয়ার সম্ভাবনাও রয়েছে, কারণ মেশিন শব্দের আকারের চেয়ে অক্ষর কম। এটি, আমি বিশ্বাস করি, চরগুলি চরগুলি পরিবর্তে ইনট ব্যবহার করে প্রয়োগ করা হয়।

আপনি যদি সত্যিই পরিষ্কার শব্দার্থবিজ্ঞান চান, তবে আমি আপনার নিজের বুলিয়ান ক্লাস তৈরির পরামর্শটিও পছন্দ করি - একটি বুলের মতো দেখায়, একটি বুলের মতো কাজ করে, তবে টেমপ্লেট বিশেষতাকে বোকা বানাও।

এছাড়াও, যে ক্লাবগুলিতে ভেক্টর <bool> বিশেষীকরণ চান তা সি ++ স্ট্যান্ডার্ড থেকে বিট করুন (বিট_ভেক্টর সহ এটি প্রতিস্থাপন করুন) চান। সমস্ত শান্ত বাচ্চারা এখানে আউট আছে :)।


4

এই সমস্যা ইতিমধ্যে ছিল আলোচনা comp.lang.c উপর ++,। সংযত। প্রস্তাবিত সমাধান:

  • আপনার নিজস্ব বরাদ্দকারী (ভিত্তিক std::allocator) এবং নিজস্ব ভেক্টর বিশেষীকরণ;
  • ব্যবহার std::deque(যত তাড়াতাড়ি একটি বই এস মায়ার্সে সুপারিশ করা হয়েছিল) - তবে এটি আপনার প্রয়োজনীয়তার জন্য নয়;
  • পিওডি boolমোড়ক তৈরি করুন;
  • পরিবর্তে একই আকারের কিছু ( char/ int/ ইত্যাদি) boolব্যবহার করুন bool;

এছাড়াও প্রারম্ভিক আমি স্ট্যান্ডার্ড কমিটির জন্য প্রস্তাব দেখেছি - STD_VECTOR_BOOL_SPECIALএই বিশেষীকরণটিকে অস্বীকার করার জন্য ম্যাক্রো (যেমন কিছু ) প্রবর্তন করুন - কিন্তু এএএফআইকে এই প্রস্তাবটি কার্যকরভাবে প্রয়োগ করা হয়নি এবং অনুমোদিত হয়নি।

দেখে মনে হচ্ছে আপনার সমস্যাটির সুন্দরভাবে এটি করার কোনও উপায় নেই ... সম্ভবত সি ++ 0x এ।


3

সহজ উত্তর ব্যবহার vector<struct sb>যেখানে sbহয় struct {boolean b};। তাহলে আপনি বলতে পারেন push_back({true})। ভাল লাগছে।


2

আমার পছন্দের কার্যসংক্রান্ত একটি হল vectorএকটি scoped enum একজন অন্তর্নিহিত টাইপ হয়েছে যে bool। এটি vector<bool>কমিটির বিশেষত্ব না রাখলে আমাদের যে হত তা খুব কাছাকাছি চলে যায় ।

enum class switch_status : bool { ON, OFF };

static_assert( sizeof( switch_status ) == 1 );

::std::vector<switch_status> switches( 20, switch_status::ON );

static_assert( ::std::is_same_v< decltype( switches.front() ), switch_status &> );
static_assert( ::std::is_same_v< decltype( switches.back()  ), switch_status &> );
static_assert( ::std::is_same_v< decltype( switches[ 0 ]    ), switch_status &> );

ক্যাসেটগুলিকে আলিঙ্গন করার / তার থেকে বুদ্ধি সম্পর্কে আপনার নিজস্ব মতামত থাকবে bool:

enum class switch_status : bool { OFF = false, ON = true };

static_assert( static_cast< bool          >( switch_status::ON  ) == true               );
static_assert( static_cast< bool          >( switch_status::OFF ) == false              );
static_assert( static_cast< switch_status >( true               ) == switch_status::ON  );
static_assert( static_cast< switch_status >( false              ) == switch_status::OFF );
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.