Initializing vectors in one line

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Emanuel Ziegler

    Initializing vectors in one line

    Hi,

    I am using the vector class from the STL. Normally, I initialize values
    element by element, which is very uncomfortable and sometimes impossible
    (e.g. when passing a constant vector to an inherited constructor, since I
    cannot create a temporary vector before calling).

    Is there a possibility to assign a vector in one line, like it is possible
    for arrays?

    I want to write code like this:

    #include <vector>
    typedef std::vector<int > ivec;
    void test (ivec w) {};
    int main () {
    // Is there a possibility to make these lines valid
    // (e.g. by extending the vector class)?
    ivec v = {1, 2};
    v = {3, 4};
    test({5, 6});
    return 0;
    }

    Is there at least a workaround for calling

    aconstructor () : inheritedconstr uctor({5, 6}) {
    ...
    }

    where inheritedconstr uctor needs a vector?


    Please help,
    Emanuel

  • John Harrison

    #2
    Re: Initializing vectors in one line


    "Emanuel Ziegler" <eziegler@web.d e> wrote in message
    news:c1ied4$1c5 $1@news.urz.uni-heidelberg.de.. .[color=blue]
    > Hi,
    >
    > I am using the vector class from the STL. Normally, I initialize values
    > element by element, which is very uncomfortable and sometimes impossible
    > (e.g. when passing a constant vector to an inherited constructor, since I
    > cannot create a temporary vector before calling).
    >
    > Is there a possibility to assign a vector in one line, like it is possible
    > for arrays?
    >
    > I want to write code like this:
    >
    > #include <vector>
    > typedef std::vector<int > ivec;
    > void test (ivec w) {};
    > int main () {
    > // Is there a possibility to make these lines valid
    > // (e.g. by extending the vector class)?
    > ivec v = {1, 2};
    > v = {3, 4};
    > test({5, 6});
    > return 0;
    > }
    >
    > Is there at least a workaround for calling
    >
    > aconstructor () : inheritedconstr uctor({5, 6}) {
    > ...
    > }
    >
    > where inheritedconstr uctor needs a vector?
    >
    >
    > Please help,
    > Emanuel
    >[/color]

    How about this? No need for a new type of vector.

    #include <vector>
    typedef std::vector<int > ivec;

    const int one_two[] = { 1, 2 };
    const int three_four[] = { 3, 4 };
    const int five_six[] = { 5, 6 };

    void test (ivec w) {};
    int main () {
    ivec v(one_two, one_two + 2);
    v = ivec(three_four , three_four + 2);
    test(ivec(five_ six, five_six + 2));
    return 0;
    }

    john



    Comment

    • Sharad Kala

      #3
      Re: Initializing vectors in one line


      "Emanuel Ziegler" <eziegler@web.d e> wrote in message
      news:c1ied4$1c5 $1@news.urz.uni-heidelberg.de.. .[color=blue]
      > Hi,
      >
      > I am using the vector class from the STL. Normally, I initialize values
      > element by element, which is very uncomfortable and sometimes impossible
      > (e.g. when passing a constant vector to an inherited constructor, since I
      > cannot create a temporary vector before calling).
      >
      > Is there a possibility to assign a vector in one line, like it is possible
      > for arrays?
      >
      > I want to write code like this:
      >
      > #include <vector>
      > typedef std::vector<int > ivec;
      > void test (ivec w) {};
      > int main () {
      > // Is there a possibility to make these lines valid
      > // (e.g. by extending the vector class)?
      > ivec v = {1, 2};
      > v = {3, 4};
      > test({5, 6});
      > return 0;
      > }
      >[/color]

      You should probably see all the vector constructors.
      Here is a demo code -

      #include <vector>
      #include <iostream>
      using namespace std;

      int main(){
      typedef vector<int> intVec;
      intVec vec(10, 5);

      intVec::const_i terator it;
      for( it=vec.begin(); it!=vec.end(); it++)
      cout << *it; // Print 5 ten times.

      int arr[]={1, 2, 3, 4};
      intVec vec2(arr, arr+4);
      for( it=vec2.begin() ; it!=vec2.end(); it++)
      cout << *it; // Print 1234

      }


      Comment

      • John Carson

        #4
        Re: Initializing vectors in one line

        "John Harrison" <john_andronicu s@hotmail.com> wrote in message
        news:c1igna$1j6 2gf$1@ID-196037.news.uni-berlin.de[color=blue]
        >
        > How about this? No need for a new type of vector.
        >
        > #include <vector>
        > typedef std::vector<int > ivec;
        >
        > const int one_two[] = { 1, 2 };
        > const int three_four[] = { 3, 4 };
        > const int five_six[] = { 5, 6 };
        >
        > void test (ivec w) {};
        > int main () {
        > ivec v(one_two, one_two + 2);
        > v = ivec(three_four , three_four + 2);
        > test(ivec(five_ six, five_six + 2));
        > return 0;
        > }
        >
        > john[/color]

        As an alternative to

        v = ivec(three_four , three_four + 2);

        you can also use:

        v.assign(three_ four, three_four + 2);


        --
        John Carson
        1. To reply to email address, remove donald
        2. Don't reply to email address (post here instead)

        Comment

        • tom_usenet

          #5
          Re: Initializing vectors in one line

          On Wed, 25 Feb 2004 16:19:00 +0100, Emanuel Ziegler <eziegler@web.d e>
          wrote:
          [color=blue]
          >Hi,
          >
          >I am using the vector class from the STL. Normally, I initialize values
          >element by element, which is very uncomfortable and sometimes impossible
          >(e.g. when passing a constant vector to an inherited constructor, since I
          >cannot create a temporary vector before calling).
          >
          >Is there a possibility to assign a vector in one line, like it is possible
          >for arrays?[/color]

          There are many ways, but all require you to write or use some kind of
          library. There have been various posts on this in the past (try google
          groups), and there are a couple of free STL initialization libraries
          around: http://www.cs.auc.dk/~nesotto/init/ and
          This page provides a list of the pages of BDSoft.com, and a little info about each one. If you are lost on our site, try using the sitemap to find what you are looking for.


          The former looks better to me, since it doesn't rely on string
          parsing.

          Tom
          --
          C++ FAQ: http://www.parashift.com/c++-faq-lite/
          C FAQ: http://www.eskimo.com/~scs/C-faq/top.html

          Comment

          • Emanuel Ziegler

            #6
            Re: Initializing vectors in one line

            John Harrison wrote:[color=blue]
            > #include <vector>
            > typedef std::vector<int > ivec;
            >
            > const int one_two[] = { 1, 2 };
            > const int three_four[] = { 3, 4 };
            > const int five_six[] = { 5, 6 };
            >
            > void test (ivec w) {};
            > int main () {
            > ivec v(one_two, one_two + 2);
            > v = ivec(three_four , three_four + 2);
            > test(ivec(five_ six, five_six + 2));
            > return 0;
            > }[/color]

            This seems to be a practical solution, although I need to define the
            constants first (not really a one-liner, but I can live with it).

            Thanks,
            Emanuel

            Comment

            • Emanuel Ziegler

              #7
              Re: Initializing vectors in one line

              tom_usenet wrote:[color=blue]
              > There are many ways, but all require you to write or use some kind of
              > library. There have been various posts on this in the past (try google
              > groups), and there are a couple of free STL initialization libraries
              > around: http://www.cs.auc.dk/~nesotto/init/ and
              > http://www.bdsoft.com/tools/initutil.html
              >
              > The former looks better to me, since it doesn't rely on string
              > parsing.[/color]

              Hmm, the first library has a very elegant implementation, but uses an
              unusual syntax and does only allow initializations . The second library uses
              a very intuitive syntax and can also be used as a parameter when calling
              functions, but it uses strings.
              Hard decision...

              Thanks,
              Emanuel

              Comment

              • Emanuel Ziegler

                #8
                Re: Initializing vectors in one line

                tom_usenet wrote:[color=blue]
                > There are many ways, but all require you to write or use some kind of
                > library. There have been various posts on this in the past (try google
                > groups), and there are a couple of free STL initialization libraries
                > around: http://www.cs.auc.dk/~nesotto/init/ and
                > http://www.bdsoft.com/tools/initutil.html[/color]

                By looking at the libraries above I had one very simple idea:

                --- source begins here ---

                #include <iostream>
                #include <vector>

                using namespace std;

                template <class T, class A = allocator<T> >
                class myvector : public vector<T,A> {
                public:
                // call inherited constructors
                explicit myvector (const A &alloc = A())
                : vector<T,A>(all oc)
                {}
                explicit myvector (size_type n,
                const T& value = T(),
                const A& alloc = A())
                : vector<T,A>(n,v alue,alloc)
                {}
                template <class InputIterator>
                myvector (InputIterator first,
                InputIterator last,
                const A &alloc = A())
                : vector<T,A>(fir st,last,alloc)
                {}
                myvector (const vector<T,A> &x)
                : vector<T,A>(x)
                {}
                using vector<T,A>::op erator=;
                // providing new functionality
                myvector & operator= (T newitem) {
                clear();
                push_back(newit em);
                return *this;
                }
                myvector & operator+= (T newitem) {
                push_back(newit em);
                return *this;
                }
                myvector & operator, (T newitem) {
                push_back(newit em);
                return *this;
                }
                };

                typedef myvector<int> ivec;

                void printivec (ivec v) {
                cout << v[0];
                for ( int i = 1; i < v.size(); i++ )
                cout << ", " << v[i];
                cout << endl;
                }

                int main () {
                myvector<int> v;
                v = 1, 2, 3; // set vector
                v += 4, 5, 6; // append items
                printivec((ivec (0), 1, 2)); // 1, 2
                printivec((ivec (v), 7, 8)); // 1, 2, 3, 4, 5, 6, 7, 8
                printivec((v, 7, 8)); // be careful: this syntax changes v !
                printivec(v); // 1, 2, 3, 4, 5, 6, 7, 8
                }

                --- source ends here ---

                Is there a more elegant way to make all inherited constructors work in the
                derived class?

                The first two printivec calls may produce memory leaks on some compilers.


                Thanks for the inspiration,
                Emanuel

                Comment

                • Emanuel Ziegler

                  #9
                  Re: Initializing vectors in one line

                  typedef typename A::size_type size_type;

                  is missing in the declaration of myvector directly before public

                  Sorry,
                  Emanuel

                  Comment

                  • Jonathan Turkanis

                    #10
                    Re: Initializing vectors in one line


                    "Emanuel Ziegler" <eziegler@web.d e> wrote in message
                    news:c1ied4$1c5 $1@news.urz.uni-heidelberg.de.. .[color=blue]
                    > Hi,
                    >
                    > I am using the vector class from the STL. Normally, I initialize[/color]
                    values[color=blue]
                    > element by element, which is very uncomfortable and sometimes[/color]
                    impossible[color=blue]
                    > (e.g. when passing a constant vector to an inherited constructor,[/color]
                    since I[color=blue]
                    > cannot create a temporary vector before calling).[/color]

                    You might want to check out Thorsten Ottosen's Assign Library,
                    submitted to boost for review and featured in a recent CUJ article:

                    Latest news coverage, email, free stock quotes, live scores and video are just the beginning. Discover more every day at Yahoo!


                    (To get access, you have to sign up for the boost developers list:
                    http://lists.boost.org/mailman/listinfo.cgi/boost)

                    Jonathan


                    Comment

                    • Leor Zolman

                      #11
                      Re: Initializing vectors in one line

                      On Wed, 25 Feb 2004 19:54:18 +0100, Emanuel Ziegler <eziegler@web.d e>
                      wrote:
                      [color=blue]
                      >tom_usenet wrote:[color=green]
                      >> There are many ways, but all require you to write or use some kind of
                      >> library. There have been various posts on this in the past (try google
                      >> groups), and there are a couple of free STL initialization libraries
                      >> around: http://www.cs.auc.dk/~nesotto/init/ and
                      >> http://www.bdsoft.com/tools/initutil.html[/color]
                      >
                      >By looking at the libraries above I had one very simple idea:
                      >
                      >--- source begins here ---
                      >
                      >#include <iostream>
                      >#include <vector>
                      >
                      >using namespace std;
                      >
                      >template <class T, class A = allocator<T> >
                      >class myvector : public vector<T,A> {
                      > public:
                      > // call inherited constructors
                      > explicit myvector (const A &alloc = A())
                      > : vector<T,A>(all oc)
                      > {}
                      > explicit myvector (size_type n,
                      > const T& value = T(),
                      > const A& alloc = A())
                      > : vector<T,A>(n,v alue,alloc)
                      > {}
                      > template <class InputIterator>
                      > myvector (InputIterator first,
                      > InputIterator last,
                      > const A &alloc = A())
                      > : vector<T,A>(fir st,last,alloc)
                      > {}
                      > myvector (const vector<T,A> &x)
                      > : vector<T,A>(x)
                      > {}
                      > using vector<T,A>::op erator=;
                      > // providing new functionality
                      > myvector & operator= (T newitem) {
                      > clear();
                      > push_back(newit em);
                      > return *this;
                      > }
                      > myvector & operator+= (T newitem) {
                      > push_back(newit em);
                      > return *this;
                      > }
                      > myvector & operator, (T newitem) {
                      > push_back(newit em);
                      > return *this;
                      > }
                      >};
                      >
                      >typedef myvector<int> ivec;
                      >
                      >void printivec (ivec v) {
                      > cout << v[0];
                      > for ( int i = 1; i < v.size(); i++ )
                      > cout << ", " << v[i];
                      > cout << endl;
                      >}
                      >
                      >int main () {
                      > myvector<int> v;
                      > v = 1, 2, 3; // set vector
                      > v += 4, 5, 6; // append items
                      > printivec((ivec (0), 1, 2)); // 1, 2
                      > printivec((ivec (v), 7, 8)); // 1, 2, 3, 4, 5, 6, 7, 8
                      > printivec((v, 7, 8)); // be careful: this syntax changes v !
                      > printivec(v); // 1, 2, 3, 4, 5, 6, 7, 8
                      >}
                      >
                      >--- source ends here ---
                      >
                      >Is there a more elegant way to make all inherited constructors work in the
                      >derived class?
                      >
                      >The first two printivec calls may produce memory leaks on some compilers.
                      >
                      >
                      >Thanks for the inspiration,
                      >Emanuel[/color]

                      Nice, elegant idea. I got to wondering whether you can generalize it
                      further, making the container type a template parameter. There's probably a
                      better way than this, but here's a version that works for both vectors and
                      deques, at least:

                      //
                      // First stab at container-independent version...
                      //

                      #include <iostream>
                      #include <vector>
                      #include <list>
                      #include <deque>

                      using namespace std;

                      template <class C, class T, class A = allocator<T> >
                      class mycont : public C {
                      typedef typename A::size_type size_type;
                      public:
                      // call inherited constructors
                      explicit mycont (const A &alloc = A())
                      : C(alloc)
                      {}
                      explicit mycont (size_type n,
                      const T& value = T(),
                      const A& alloc = A())
                      : C(n,value,alloc )
                      {}
                      template <class InputIterator>
                      mycont (InputIterator first,
                      InputIterator last,
                      const A &alloc = A())
                      : C(first,last,al loc)
                      {}
                      mycont (const C &x)
                      : C(x)
                      {}
                      using C::operator=;
                      // providing new functionality
                      mycont & operator= (T newitem) {
                      C::clear();
                      C::push_back(ne witem);
                      return *this;
                      }
                      mycont & operator+= (T newitem) {
                      C::push_back(ne witem);
                      return *this;
                      }
                      mycont & operator, (T newitem) {
                      C::push_back(ne witem);
                      return *this;
                      }
                      };

                      typedef mycont<std::vec tor<int>,int> ivec;
                      typedef mycont<std::deq ue<double>,doub le> ddeq;


                      // templatized this ( for containers with subscripting, at least...)
                      // A ready-made equivalent for all containers is part of Scott Meyers'
                      // ESTLUtil.h, the latest version of which is included in the InitUtil v2
                      // distribution.

                      template<class T>
                      void printivec (const T &t) {
                      cout << t[0];
                      for ( int i = 1; i < t.size(); i++ )
                      cout << ", " << t[i];
                      cout << endl;
                      }

                      int main () {
                      ivec v;
                      v = 1, 2, 3; // set vector
                      v += 4, 5, 6; // append items
                      printivec((ivec (0), 1, 2)); // 1, 2
                      printivec((ivec (v), 7, 8)); // 1, 2, 3, 4, 5, 6, 7, 8
                      printivec((v, 7, 8)); // be careful: this syntax changes v !
                      printivec(v); // 1, 2, 3, 4, 5, 6, 7, 8

                      ddeq d; // deque of doubles
                      d = 1, 2.5, 3; // set deque
                      d += 4, 5, 6.6; // append items
                      printivec((ddeq (0), 1, 2)); // 1, 2
                      printivec((ddeq (d), 7, 8)); // 1, 2, 3, 4, 5, 6, 7, 8
                      printivec((d, 7, 8)); // be careful: this syntax changes v !
                      printivec(d); // 1, 2, 3, 4, 5, 6, 7, 8

                      return 0;
                      }


                      -leor


                      Leor Zolman
                      BD Software
                      leor@bdsoft.com
                      www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
                      C++ users: Download BD Software's free STL Error Message
                      Decryptor at www.bdsoft.com/tools/stlfilt.html

                      Comment

                      • Thorsten Ottosen

                        #12
                        Re: Initializing vectors in one line

                        "Emanuel Ziegler" <eziegler@web.d e> wrote in message
                        news:c1im88$6eo $1@news.urz.uni-heidelberg.de.. .[color=blue]
                        > tom_usenet wrote:[color=green]
                        > > There are many ways, but all require you to write or use some kind of
                        > > library. There have been various posts on this in the past (try google
                        > > groups), and there are a couple of free STL initialization libraries
                        > > around: http://www.cs.auc.dk/~nesotto/init/ and[/color][/color]

                        Please note as the page says that the contents is depricated; The newest
                        source and documentation
                        is found ihe boost sandbox:

                        Download Boost Sandbox for free. The Boost Sandbox is the location for collaboration on potential Boost libraries, that is, libraries that are in development with the purpose of submiting the library to Boost (www.boost.org).

                        Download Boost Sandbox for free. The Boost Sandbox is the location for collaboration on potential Boost libraries, that is, libraries that are in development with the purpose of submiting the library to Boost (www.boost.org).

                        [color=blue][color=green]
                        > > http://www.bdsoft.com/tools/initutil.html
                        > >
                        > > The former looks better to me, since it doesn't rely on string
                        > > parsing.[/color]
                        >
                        > Hmm, the first library has a very elegant implementation, but uses an
                        > unusual syntax and does only allow initializations .[/color]

                        Do you still think that about the current library?

                        br

                        Thorsten


                        Comment

                        • Thorsten Ottosen

                          #13
                          Re: Initializing vectors in one line

                          "Emanuel Ziegler" <eziegler@web.d e> wrote in message
                          news:c1ied4$1c5 $1@news.urz.uni-heidelberg.de.. .[color=blue]
                          > Hi,[/color]
                          [color=blue]
                          > Is there a possibility to assign a vector in one line, like it is possible
                          > for arrays?[/color]

                          Probably not if it should be optmially efficient. FYI the standard committee
                          is discussing
                          added such a facility to the langauage.

                          br

                          Thorsten


                          Comment

                          • Leor Zolman

                            #14
                            Re: Initializing vectors in one line

                            On Thu, 26 Feb 2004 03:46:45 GMT, Leor Zolman <leor@bdsoft.co m> wrote:

                            Duh, one obvious thing I should have done right away is change this:
                            [color=blue]
                            >
                            >template <class C, class T, class A = allocator<T> >
                            >class mycont : public C {
                            > typedef typename A::size_type size_type;
                            >public:[/color]

                            to:

                            template <class C, class A = allocator<typen ame C::value_type> >
                            class mycont : public C {
                            typedef typename A::size_type size_type;
                            typedef typename C::value_type T;
                            public:

                            so that later these:
                            [color=blue]
                            >
                            >typedef mycont<std::vec tor<int>,int> ivec;
                            >typedef mycont<std::deq ue<double>,doub le> ddeq;
                            >[/color]
                            can be written as just:

                            typedef mycont<std::vec tor<int> > ivec;
                            typedef mycont<std::deq ue<double> > ddeq;


                            -leor


                            Leor Zolman
                            BD Software
                            leor@bdsoft.com
                            www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
                            C++ users: Download BD Software's free STL Error Message
                            Decryptor at www.bdsoft.com/tools/stlfilt.html

                            Comment

                            • tom_usenet

                              #15
                              Re: Initializing vectors in one line

                              On Wed, 25 Feb 2004 19:54:18 +0100, Emanuel Ziegler <eziegler@web.d e>
                              wrote:
                              [color=blue]
                              >tom_usenet wrote:[color=green]
                              >> There are many ways, but all require you to write or use some kind of
                              >> library. There have been various posts on this in the past (try google
                              >> groups), and there are a couple of free STL initialization libraries
                              >> around: http://www.cs.auc.dk/~nesotto/init/ and
                              >> http://www.bdsoft.com/tools/initutil.html[/color]
                              >
                              >By looking at the libraries above I had one very simple idea:[/color]

                              It's already been added to Thorsten's library, and it doesn't use
                              inheritence (which has problems). Note that operator+= doesn't need to
                              be a member function....



                              Tom
                              --
                              C++ FAQ: http://www.parashift.com/c++-faq-lite/
                              C FAQ: http://www.eskimo.com/~scs/C-faq/top.html

                              Comment

                              Working...