how-to initialize 'const std::vector' like a c array

后端 未结 10 708
走了就别回头了
走了就别回头了 2020-11-27 02:59

Is there an elegant way to create and initialize a const std::vector like const T a[] = { ... } to a fixed (and small) number of val

相关标签:
10条回答
  • 2020-11-27 03:24

    Old question, but I ran into the same issue today, here's the approach that was most acceptable for my purposes:

    vector<int> initVector(void)
    {
        vector<int> initializer;
        initializer.push_back(10);
        initializer.push_back(13);
        initializer.push_back(3);
        return intializer;
    }
    
    int main()
    {
        const vector<int> a = initVector();
        return 0;
    }
    

    Example to avoid excessive copying:

    vector<int> & initVector(void)
    {
        static vector<int> initializer;
        if(initializer.empty())
        {
            initializer.push_back(10);
            initializer.push_back(13);
            initializer.push_back(3);
        }
        return intializer;
    }
    
    int main()
    {
        const vector<int> & a = initVector();
        return 0;
    }
    
    0 讨论(0)
  • 2020-11-27 03:26

    As others have said, you can't init a vector the same way you can init a C-style array, unless you give it pointers to a source array. But in that case, if your vector is a global const, why not just use an old C-style array instead?

    const int MyInts[] = {
    1, 2, 3, 4, 5};
    
    const size_t NumMyInts = sizeof(MyInts)/sizeof(MyInts[0]);
    

    You can even use STL algorithms against this array, the same way you would use algorithms against a const vector...

    const int* myInt = std::find( &MyInts[0], &MyInts[NumMyInts], 3);
    
    0 讨论(0)
  • 2020-11-27 03:35

    You can do it in two steps:

    namespace {
        const T s_actual_array[] = { ... };
        const std::vector<const T> s_blah(s_actual_array,
            s_actual_array + (sizeof(s_actual_array) / sizeof(s_actual_array[0])));
    }
    

    Perhaps not as beautiful as you might like, but functional.

    0 讨论(0)
  • 2020-11-27 03:39

    Short and dirty way (similar to Boost's list_of())

    #include <iostream>
    #include <vector>
    #include <iterator>
    #include <algorithm>
    using namespace std;
    
    template <typename T>
    struct vlist_of : public vector<T> {
        vlist_of(const T& t) {
            (*this)(t);
        }
        vlist_of& operator()(const T& t) {
            this->push_back(t);
            return *this;
        }
    };
    
    int main() {
        const vector<int> v = vlist_of<int>(1)(2)(3)(4)(5);
        copy(v.begin(), v.end(), ostream_iterator<int>(cout, "\n"));
    }
    

    Now, C++11 has initializer lists, so you don't need to do it that way or even use Boost. But, as an example, you can do the above in C++11 more efficiently like this:

        #include <iostream>
        #include <vector>
        #include <utility>
        #include <ostream>
        using namespace std;
    
        template <typename T>
        struct vlist_of : public vector<T> {
            vlist_of(T&& t) {
                (*this)(move(t));
            }
            vlist_of& operator()(T&& t) {
                this->push_back(move(t));
                return *this;
            }
        };
    
        int main() {
            const vector<int> v = vlist_of<int>(1)(2)(3)(4)(5);
            for (const auto& i: v) {
                cout << i << endl;
            }
        }
    

    But, it's still not as efficient as using a C++11 initializer list because there's no operator=(vlist_of&&) defined for vector.

    tjohns20's way modified like the following might be a better c++11 vlist_of:

    #include <iostream>
    #include <vector>
    #include <utility>
    using namespace std;
    
    template <typename T>
    class vlist_of {
        public:
            vlist_of(T&& r) {
                (*this)(move(r));
            }
            vlist_of& operator()(T&& r) {
                v.push_back(move(r));
                return *this;
            }
            vector<T>&& operator()() {
                return move(v);
            }
        private:
            vector<T> v;
        
    };
    
    int main() {
        const auto v = vlist_of<int>(1)(2)(3)(4)(5)();
        for (const auto& i : v) {
            cout << i << endl;
        }
        
    }
    
    0 讨论(0)
提交回复
热议问题