c++ - हार्डकोडेड तत्वों के साथ std:: वेक्टर प्रारंभ करने का सबसे आसान तरीका क्या है?




vector initialization (16)

आप बूस्ट :: असाइनमेंट का उपयोग कर ऐसा कर सकते हैं।

vector<int> values;  
values += 1,2,3,4,5,6,7,8,9;

यहां विस्तार करें

मैं एक सरणी बना सकता हूं और इसे इस तरह शुरू कर सकता हूं:

int a[] = {10, 20, 30};

मैं एक std::vector कैसे बना सकता हूं और इसे समान रूप से सुरुचिपूर्ण कैसे बना सकता हूं?

मुझे पता है कि सबसे अच्छा तरीका है:

std::vector<int> ints;

ints.push_back(10);
ints.push_back(20);
ints.push_back(30);

क्या कोई बेहतर तरीका है?


ऐसा करने का सबसे आसान तरीका यह है:

vector<int> ints = {10, 20, 30};

बस सोचा कि मैं अपने $ 0.02 में टॉस करूंगा। मैं यह घोषणा करता हूं:

template< typename T, size_t N >
std::vector<T> makeVector( const T (&data)[N] )
{
    return std::vector<T>(data, data+N);
}

किसी यूटिलिटी हेडर में कहीं और फिर यह आवश्यक है:

const double values[] = { 2.0, 1.0, 42.0, -7 };
std::vector<double> array = makeVector(values);

लेकिन मैं सी ++ 0x के लिए इंतजार नहीं कर सकता। मैं अटक गया हूं क्योंकि मेरा कोड विजुअल स्टूडियो में भी संकलित होना चाहिए। बू।


बी स्ट्रॉस्ट्रप 16.2.10 में चेन ऑपरेशंस के लिए एक अच्छा तरीका बताता है , पेज 464 पर प्रोग्रेस के सी ++ 11 संस्करण में आत्मविश्वास । लैंग। जहां एक समारोह एक संदर्भ देता है, यहां एक वेक्टर में संशोधित किया गया है। इस तरह आप v.pb(1).pb(2).pb(3); तरह श्रृंखला कर सकते हैं v.pb(1).pb(2).pb(3); लेकिन इस तरह के छोटे लाभ के लिए बहुत अधिक काम हो सकता है।

#include <iostream>
#include <vector>

template<typename T>
class chain
{
private:
    std::vector<T> _v;
public:
    chain& pb(T a) {
        _v.push_back(a);
        return *this;
    };
    std::vector<T> get() { return _v; };
};

using namespace std;

int main(int argc, char const *argv[])
{
    chain<int> v{};

    v.pb(1).pb(2).pb(3);

    for (auto& i : v.get()) {
        cout << i << endl;
    }

    return 0;
}

1
2
3


यदि आप Boost :: बूस्ट पर निर्भरता बनाए बिना असाइनमेंट के समान सामान्य आदेश पर कुछ चाहते हैं, तो निम्न कम से कम अस्पष्ट रूप से समान है:

template<class T>
class make_vector {
    std::vector<T> data;
public:
    make_vector(T const &val) { 
        data.push_back(val);
    }

    make_vector<T> &operator,(T const &t) {
        data.push_back(t);
        return *this;
    }

    operator std::vector<T>() { return data; }
};

template<class T> 
make_vector<T> makeVect(T const &t) { 
    return make_vector<T>(t);
}

जबकि मैं चाहता हूं कि इसका उपयोग करने के लिए सिंटैक्स क्लीनर था, यह अभी भी विशेष रूप से भयानक नहीं है:

std::vector<int> x = (makeVect(1), 2, 3, 4);

यदि आप बूस्ट का उपयोग नहीं करना चाहते हैं, लेकिन सिंटैक्स का आनंद लेना चाहते हैं

std::vector<int> v;
v+=1,2,3,4,5;

बस कोड का यह हिस्सा शामिल करें

template <class T> class vector_inserter{
public:
    std::vector<T>& v;
    vector_inserter(std::vector<T>& v):v(v){}
    vector_inserter& operator,(const T& val){v.push_back(val);return *this;}
};
template <class T> vector_inserter<T> operator+=(std::vector<T>& v,const T& x){
    return vector_inserter<T>(v),x;
}

यदि आपका कंपाइलर सी ++ 11 का समर्थन करता है, तो आप बस ऐसा कर सकते हैं:

std::vector<int> v = {1, 2, 3, 4};

यह जीसीसी में संस्करण 4.4 के रूप में उपलब्ध है। दुर्भाग्यवश, वीसी ++ 2010 इस संबंध में पीछे हट रहा है।

वैकल्पिक रूप से, Boost.Assign लाइब्रेरी निम्न अनुमति देने के लिए गैर-मैक्रो जादू का उपयोग करता है:

#include <boost/assign/list_of.hpp>
...
std::vector<int> v = boost::assign::list_of(1)(2)(3)(4);

या:

#include <boost/assign/std/vector.hpp>
using namespace boost::assign;
...
std::vector<int> v;
v += 1, 2, 3, 4;

लेकिन ध्यान रखें कि इसमें कुछ ओवरहेड है (मूल रूप से, list_of हुड के नीचे एक std::deque ) ताकि प्रदर्शन-महत्वपूर्ण कोड के लिए आप योकॉबी के कहने से बेहतर हो जाएंगे।


यदि सरणी है:

int arr[] = {1, 2, 3};
int len = (sizeof(arr)/sizeof(arr[0])); // finding length of array
vector < int > v;
std:: v.assign(arr, arr+len); // assigning elements from array to vector 

वेक्टर प्रारंभिकरण के लिए -

vector<int> v = {10,20,30}

यदि आपके पास सी ++ 11 कंपाइलर है तो किया जा सकता है।

अन्यथा, आपके पास डेटा की एक सरणी हो सकती है और फिर लूप का उपयोग कर सकते हैं।

int array[] = {10,20,30}
for(int i=0; i<sizeof(array); i++)
     v.push_back(array[i]);

इनके अलावा, कुछ कोड का उपयोग करके ऊपर वर्णित कई अन्य तरीके हैं। मेरी राय में, इन तरीकों को याद रखना और लिखना आसान है।


वेक्टर शुरू करने के लिए सरणी का उपयोग करने के लिए एक विधि होगी

static const int arr[] = {16,2,77,29};
vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );

सी ++ 0x में आप इसे उसी तरह से करने में सक्षम होंगे जैसे आपने सरणी के साथ किया था, लेकिन वर्तमान मानक में नहीं।

केवल भाषा समर्थन के साथ आप इसका उपयोग कर सकते हैं:

int tmp[] = { 10, 20, 30 };
std::vector<int> v( tmp, tmp+3 ); // use some utility to avoid hardcoding the size here

यदि आप अन्य पुस्तकालय जोड़ सकते हैं तो आप बूस्ट :: असाइनमेंट का प्रयास कर सकते हैं:

vector<int> v = list_of(10)(20)(30);

सरणी के आकार को हार्डकोडिंग से बचने के लिए:

// option 1, typesafe, not a compile time constant
template <typename T, std::size_t N>
inline std::size_t size_of_array( T (&)[N] ) {
   return N;
}
// option 2, not typesafe, compile time constant
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))

// option 3, typesafe, compile time constant
template <typename T, std::size_t N>
char (&sizeof_array( T(&)[N] ))[N];    // declared, undefined
#define ARRAY_SIZE(x) sizeof(sizeof_array(x))

सी ++ 11 में:

#include <vector>
using std::vector;
...
vector<int> vec1 { 10, 20, 30 };
// or
vector<int> vec2 = { 10, 20, 30 };

बूस्ट list_of का उपयोग करना:

#include <vector>
#include <boost/assign/list_of.hpp>
using std::vector;
...
vector<int> vec = boost::assign::list_of(10)(20)(30);

बूस्ट असाइन का उपयोग करना:

#include <vector>
#include <boost/assign/std/vector.hpp>
using std::vector;
...
vector<int> vec;
vec += 10, 20, 30;

पारंपरिक एसटीएल:

#include <vector>
using std::vector;
...
static const int arr[] = {10,20,30};
vector<int> vec (arr, arr + sizeof(arr) / sizeof(arr[0]) );

जेनेरिक मैक्रोज़ के साथ पारंपरिक एसटीएल:

#include <vector>
#define ARRAY_SIZE(ar) (sizeof(ar) / sizeof(ar[0])
#define ARRAY_END(ar) (ar + ARRAY_SIZE(ar))
using std::vector;
...
static const int arr[] = {10,20,30};
vector<int> vec (arr, ARRAY_END(arr));

एक वेक्टर प्रारंभकर्ता मैक्रो के साथ पारंपरिक एसटीएल:

#include <vector>
#define INIT_FROM_ARRAY(ar) (ar, ar + sizeof(ar) / sizeof(ar[0])
using std::vector;
...
static const int arr[] = {10,20,30};
vector<int> vec INIT_FROM_ARRAY(arr);

सी ++ 11 से पहले:

विधि 1 =>

vector<int> v(arr, arr + sizeof(arr)/sizeof(arr[0]));
vector<int>v;

विधि 2 =>

 v.push_back(SomeValue);

सी ++ 11 आगे नीचे भी संभव है

vector<int>v = {1, 3, 5, 7};

सी ++ में वेक्टर को प्रारंभ करने के लिए विधियों का उपयोग किया जा सकता है।

  1. int arr[] = {1, 3, 5, 6}; vector<int> v(arr, arr + sizeof(arr)/sizeof(arr[0]));

  2. vector<int>v; v.push_back(1); v.push_back(2); v.push_back(3); और इसी तरह

  3. vector<int>v = {1, 3, 5, 7};

तीसरे व्यक्ति को केवल सी ++ 11 में ही अनुमति दी जाती है।


विक्टर सेहर ने हाल ही में एक डुप्लिकेट प्रश्न का जवाब दिया है। मेरे लिए, यह कॉम्पैक्ट, दृष्टि से आकर्षक है (ऐसा लगता है कि आप मूल्यों को 'shoving' कर रहे हैं), c ++ 11 या किसी तृतीय पक्ष मॉड्यूल की आवश्यकता नहीं है, और एक अतिरिक्त (लिखित) चर का उपयोग करने से बचाता है। नीचे मैं कुछ बदलावों के साथ इसका उपयोग कैसे कर रहा हूं। मैं भावी intead में वेक्टर और / या va_arg के कार्य को विस्तारित करने के लिए स्विच कर सकते हैं।

// Based on answer by "Viktor Sehr" on 
// https://.com/a/8907356
//
template <typename T>
class mkvec {
public:
    typedef mkvec<T> my_type;
    my_type& operator<< (const T& val) {
        data_.push_back(val);
        return *this;
    }
    my_type& operator<< (const std::vector<T>& inVector) {
        this->data_.reserve(this->data_.size() + inVector.size());
        this->data_.insert(this->data_.end(), inVector.begin(), inVector.end());
        return *this;
    }
    operator std::vector<T>() const {
        return data_;
    }
private:
    std::vector<T> data_;
};

std::vector<int32_t>    vec1;
std::vector<int32_t>    vec2;

vec1 = mkvec<int32_t>() << 5 << 8 << 19 << 79;  
// vec1 = (5,8,19,79)
vec2 = mkvec<int32_t>() << 1 << 2 << 3 << vec1 << 10 << 11 << 12;  
// vec2 = (1,2,3,5,8,19,79,10,11,12)

// Before C++11
// I used following methods:

// 1.
int A[] = {10, 20, 30};                              // original array A

unsigned sizeOfA = sizeof(A)/sizeof(A[0]);           // calculate the number of elements

                                                     // declare vector vArrayA,
std::vector<int> vArrayA(sizeOfA);                   // make room for all
                                                     // array A integers
                                                     // and initialize them to 0 

for(unsigned i=0; i<sizeOfA; i++)
    vArrayA[i] = A[i];                               // initialize vector vArrayA


//2.
int B[] = {40, 50, 60, 70};                          // original array B

std::vector<int> vArrayB;                            // declare vector vArrayB
for (unsigned i=0; i<sizeof(B)/sizeof(B[0]); i++)
    vArrayB.push_back(B[i]);                         // initialize vArrayB

//3.
int C[] = {1, 2, 3, 4};                              // original array C

std::vector<int> vArrayC;                            // create an empty vector vArrayC
vArrayC.resize(sizeof(C)/sizeof(C[0]));              // enlarging the number of 
                                                     // contained elements
for (unsigned i=0; i<sizeof(C)/sizeof(C[0]); i++)
     vArrayC.at(i) = C[i];                           // initialize vArrayC


// A Note:
// Above methods will work well for complex arrays
// with structures as its elements.




initialization