वेक्टर <bool> के लिए वैकल्पिक


92

जैसा कि (उम्मीद है) हम सभी जानते हैं, vector<bool>पूरी तरह से टूट गया है और सी सरणी के रूप में नहीं माना जा सकता है। इस कार्यक्षमता को प्राप्त करने का सबसे अच्छा तरीका क्या है? अब तक, मैंने जिन विचारों के बारे में सोचा है वे हैं:

  • vector<char>इसके बजाय, या का उपयोग करें
  • एक आवरण वर्ग का उपयोग करें और करें vector<bool_wrapper>

आप लोग इस समस्या को कैसे संभालेंगे? मुझे c_array()कार्यक्षमता की आवश्यकता है ।

एक पक्ष के प्रश्न के रूप में, अगर मुझे c_array()विधि की आवश्यकता नहीं है, तो इस समस्या से संपर्क करने का सबसे अच्छा तरीका क्या है अगर मुझे यादृच्छिक अभिगम की आवश्यकता है? क्या मुझे एक छलावा या कुछ और उपयोग करना चाहिए?

संपादित करें:

  • मुझे डायनामिक आकार देने की आवश्यकता है।
  • जो नहीं जानते, उनके vector<bool>लिए विशेष है ताकि प्रत्येक bool1 बिट ले। इस प्रकार आप इसे सी-स्टाइल ऐरे में नहीं बदल सकते।
  • मुझे लगता है कि "रैपर" एक मिथ्या नाम है। मैं कुछ इस तरह सोच रहा था:

बेशक, तब मुझे my_boolसंभावित संरेखण मुद्दों के कारण पढ़ना होगा :(

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

2
क्या कोई कारण नहीं उपयोग करने के लिए है ... एक सी-शैली सरणी?
क्विन

rlbond, क्या आपको गतिशील आकार की आवश्यकता है?
जोहान्स शाउब -

16
ठीक है मैं काटता हूँ - आपको क्यों लगता है कि वेक्टर "" पूरी तरह से टूट गया है? ''
एंड्रयू ग्रांट

8
@Andrew ग्रांट - देखें open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2160.html
डैनियल

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;
}

मैंने VC9 के साथ यह कोशिश की और यह ठीक काम करने लगता है। बूल वर्ग का विचार एक ही व्यवहार और आकार प्रदान करके बूल प्रकार का अनुकरण करना है (लेकिन एक ही प्रकार नहीं)। लगभग सभी काम बूल ऑपरेटर और डिफ़ॉल्ट कॉपी कंस्ट्रक्टर्स द्वारा किया जाता है। मैंने यह सुनिश्चित करने के लिए एक प्रकार जोड़ा कि यह एल्गोरिदम का उपयोग करते समय ग्रहण की गई प्रतिक्रिया के रूप में हो।

सुनिश्चित नहीं है कि यह सभी मामलों के अनुरूप होगा। यदि यह आपकी आवश्यकताओं के लिए सही है, तो यह एक वेक्टर जैसी कक्षा को फिर से लिखने से कम काम होगा ...


"हम बूल * ऑपरेटर और () {रिटर्न और m_value;}" जोड़ सकते हैं - गलत। आईएसओ : " sizeof(bool)होना आवश्यक नहीं है 1"
एवगेनी पनासुक

2
मैं बस operator bool() constएक को बदलने के लिए पसंद करेंगे operator bool&()। यह एक साधारण बूल के व्यवहार को बेहतर बनाता है क्योंकि यह असाइनमेंट आदि का समर्थन करता है जैसे कि v[0] = true;मैं वास्तव में इस बदलाव के साथ एक मुद्दा नहीं देख सकता हूं, इसलिए क्या मैं संपादन कर सकता हूं?
एजेंटलीयन

19

आपकी जरूरतों पर निर्भर करता है। मैं भी जाऊंगा std::vector<unsigned char>। रैपर लिखना ठीक हो सकता है यदि आप केवल कार्यक्षमता का सबसेट उपयोग करते हैं, तो यह एक बुरा सपना बन जाएगा।


unsigned charहमेशा एक ही बाइट होता है जबकि uint8_tकार्यान्वयन द्वारा समर्थित नहीं किया जा सकता है। uint_fast8_tकाम कर सकता है, हालांकि अगर इरादा यह स्पष्ट करने के लिए है कि यह एक एकल बाइट है और एक चरित्र नहीं है, लेकिन आप std::byteतब भी उपयोग कर सकते हैं
गेब्रियल रेवियर

13

आप लोग इस समस्या को कैसे संभालेंगे? मुझे c_array () कार्यक्षमता की आवश्यकता है।

boost::container::vector<bool>:

वेक्टर < bool > विशेषज्ञता काफी समस्याग्रस्त रही है, और इसे मानक से हटाने या हटाने के कई असफल प्रयास हुए हैं। Boost.Containerएक बेहतर Boost.DynamicBitset समाधान के रूप में इसे लागू नहीं करता है ।

...

तो बढ़ावा :: कंटेनर :: वेक्टर :: पुनरावृत्त वास्तविक बूल संदर्भ देता है और पूरी तरह से अनुपालन कंटेनर के रूप में काम करता है। यदि आपको बढ़ावा देने के लिए एक मेमोरी अनुकूलित संस्करण की आवश्यकता है :: कंटेनर :: वेक्टर < बूल > फ़ंक्शंस, तो Boost.DynamicBitset का उपयोग करें


6

वेक्टर <int> का उपयोग करने पर विचार करें। एक बार जब आप पिछले संकलन प्राप्त करते हैं और चेकिंग करते हैं, तो बूल और इंट दोनों सिर्फ मशीन शब्द हैं (संपादित करें: जाहिरा तौर पर यह हमेशा सच नहीं होता है; लेकिन कई पीसी आर्किटेक्चर पर सच होगा)। उन मामलों में जहां आप बिना किसी चेतावनी के परिवर्तित करना चाहते हैं, "बूल फू = !! बार" का उपयोग करें, जो शून्य को असत्य और गैर-शून्य को सत्य में परिवर्तित करता है।

एक वेक्टर <char> या समान कम जगह का उपयोग करेगा, हालांकि इसमें कुछ परिस्थितियों में एक (बहुत छोटी) गति लेने की क्षमता भी है, क्योंकि अक्षर मशीन शब्द आकार से कम हैं। यह है, मेरा मानना ​​है कि मुख्य कारण यह है कि चूलों के बजाय चींटियों का उपयोग करके बूल को लागू किया जाता है।

यदि आप वास्तव में स्वच्छ शब्दार्थ चाहते हैं, तो मुझे आपकी खुद की बूलियन क्लास बनाने का सुझाव भी पसंद है - एक बूल की तरह दिखता है, एक बूल की तरह काम करता है, लेकिन टेम्पलेट विशेषज्ञता को मूर्ख बनाता है।

इसके अलावा, उन लोगों के क्लब में आपका स्वागत है जो वेक्टर <bool> विशेषज्ञता चाहते हैं, जो C ++ मानक (इसे बदलने के लिए bit_vector के साथ) से गिरा दिया गया है। यह वह जगह है जहाँ सभी शांत बच्चे बाहर घूमते हैं :)।


4

इस समस्या पर पहले ही comp.lang.c ++ पर चर्चा की गई थी । प्रस्तावित समाधान:

  • अपने स्वयं के आवंटन (पर आधारित std::allocator) और स्वयं वेक्टर विशेषज्ञता;
  • उपयोग std::deque(जैसा कि शुरुआती पुस्तकों में एस मेयर में से एक में सिफारिश की गई थी) - लेकिन यह आपकी आवश्यकताओं के लिए नहीं है;
  • पीओडी boolआवरण बना;
  • इसके बजाय एक ही आकार के साथ कुछ ( char/ int/ आदि) का boolउपयोग करें bool;

इसके अलावा, मैंने मानक समिति के प्रस्ताव को देखा - STD_VECTOR_BOOL_SPECIALइस विशेषज्ञता को समाप्त करने के लिए मैक्रो (कुछ इस तरह का परिचय ) - लेकिन AFAIK इस प्रस्ताव को stl कार्यान्वयन में लागू नहीं किया गया था और इसे अनुमोदित नहीं किया गया था।

ऐसा लगता है कि आपकी समस्या के पास इसे अच्छी तरह से करने का कोई तरीका नहीं है ... शायद C ++ 0x में।


3

सरलतम उत्तर का उपयोग है vector<struct sb>जहां sbहै struct {boolean b};। तब आप कह सकते हैं push_back({true})। वो अच्छा लग रहा है।


2

मेरा पसंदीदा vectorवर्कआउट एक स्कॉप्ड एनम है जिसमें एक अंतर्निहित प्रकार है 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 );
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.