Topic: Critic about the standard


Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/02/18
Raw View
Luis Coelho wrote:
>
> On 16 Feb 99 06:55:59 GMT, Christopher Eltschka
> <celtschk@physik.tu-muenchen.de> uttered the following words:
> >namespace your
> >{
> >  template<typename T> class vector
> >  {
> >    template<int size>
> >      vector(T (&arr)[size])
> >    {
> >      // example implementation
> >      initialize_empty_vector();
> >      T* p=arr;
> >      for(int i=0; i<size; ++i)
> >        push_back(*p++);
> >    }
> >    ... usual vector members
> >  };
> >}
>
> Why not
>
> <code>
>
> template<typename T>
> class my_vector : public vector<T>
> {
>  public:
>  template<size_t N>
>  my_vector(T (&a)[N]):vector(a,N) {}
> };
>
> </code>
>
> My compiler seems to choke on this code, but I cannot see what's
> wrong.

Replace vector by vector<T> in the initializer list.

However, your code has another problem: Constructors are not inherited.
Therefore you will not be able to make a my_vector with any other
constructor. You _must_ repeat the constructors in the derived class.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: David R Tribble <dtribble@technologist.com>
Date: 1999/02/16
Raw View
ramon@nospam.jl1.quim.ucm.es wrote:
>
> >C++ built-in arrays are deliberately intended to be compatible
> >with arrays in C. In C, arrays are not first-class citizens,
> >and have inconsistent behavior.
>
> >If you don't want the annoying array behavior in C++, don't use
> >C-style arrays. Use class vector or valarray, or write your
> >own array class.
>
> I am already using the class vector, but the way of initializing a vector
> is rather weird:
>
> #include <vector>
>
> foo()
> {
>         int kk[] = {4, 0, 6};
>         vector vx(3, kk);
>         // work with vx
> }
>
> That is, I must evaluate by hand the number of elements (or use a
> macro, as I am doing). You can say that this is syntax sugar, and you
> are right.
...

Of course, you can always use sizeof:

        vector  vx(sizeof(kk)/sizeof(kk[0]), kk);

I think this inline function might also work:

    template <class T, size_t N>
    inline size_t arraySize(const T (&a)[N])
    {
        return N;
    }

    ...
        vector  vx(arraySize(kk), kk);

Still, neither of these solutions is as nice as having the vector
size deduced automagically.  (Which I can't help you with, I'm
afraid.)

-- David R. Tribble, dtribble@technologist.com --


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: deepblack@geocities.com (Luis Coelho)
Date: 1999/02/17
Raw View
On 16 Feb 99 06:55:59 GMT, Christopher Eltschka
<celtschk@physik.tu-muenchen.de> uttered the following words:
>namespace your
>{
>  template<typename T> class vector
>  {
>    template<int size>
>      vector(T (&arr)[size])
>    {
>      // example implementation
>      initialize_empty_vector();
>      T* p=arr;
>      for(int i=0; i<size; ++i)
>        push_back(*p++);
>    }
>    ... usual vector members
>  };
>}

Why not

<code>

template<typename T>
class my_vector : public vector<T>
{
 public:
 template<size_t N>
 my_vector(T (&a)[N]):vector(a,N) {}
};

</code>

My compiler seems to choke on this code, but I cannot see what's
wrong.

Regards,
Luis Coelho.
C++ Programming Language, 3rd Ed. by B. Stroustrup. My exercise answers at:
http://www.geocities.com/SiliconValley/Way/3972/index.html


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/02/16
Raw View
ramon@nospam.jl1.quim.ucm.es wrote:
>
> >C++ built-in arrays are deliberately intended to be compatible
> >with arrays in C. In C, arrays are not first-class citizens,
> >and have inconsistent behavior.
>
> >If you don't want the annoying array behavior in C++, don't use
> >C-style arrays. Use class vector or valarray, or write your
> >own array class.
>
> I am already using the class vector, but the way of initializing a vector
> is rather weird:
>
> #include <vector>
>
> foo()
> {
>         int kk[] = {4, 0, 6};
>         vector vx(3, kk);
>         // work with vx
> }
>
> That is, I must evaluate by hand the number of elements (or use a macro, as
> I am doing). You can say that this is syntax sugar, and you are right. But
> it would be nice if I can write something like:
>
> foo()
> {
>         int kk[] = {4, 0, 6};
>         vector vx(kk);
>         // work with vx
> }
>
> But I cannot define the neccesary constructor in the vector class (well,
> I should use a different class since vector is standards) because of the
> automatic conversion of arrays to pointers.

Well, if you use another implementation (f.ex. your::vector),
you _can_ indeed provide such a constructor:

namespace your
{
  template<typename T> class vector
  {
    template<int size>
      vector(T (&arr)[size])
    {
      // example implementation
      initialize_empty_vector();
      T* p=arr;
      for(int i=0; i<size; ++i)
        push_back(*p++);
    }
    ... usual vector members
  };
}

int a[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 };

int main()
{
  your::vector<int> v(a); // automatically calculates size
  assert(v.size()==10);
  your::vector<int> v2(3, a); // uses conventional constructor
  assert(v2.size()==3);
}

Of course, your compiler has to support member templates for that.
And certainly, you cannot give your::vector to functions expecting
std::vector (unless the exact type is templated, in which case
your::vector would act as perfect replacement for std::vector).

>
> I believe that allowing me to use the number of elements of the array as
> a template argument would not break any compatibility with C code, and it
> would be useful for some cases like this when you work with an array whose
> size is known at compile time.

I even think it wouldn't break any C++ code, since
- no language change would be necessary (see above)
- currently AFAIK no available constructor would fit the
  array-only argument call

So the above constructor template (or a slight modification
thereof) could in principle have been added to the vector
template (and to the other containers as well).

However, it's too late now anyway. (Or is it way too early?)
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Bill Wade" <bill.wade@stoner.com>
Date: 1999/02/11
Raw View
ramon@nospam.jl1.quim.ucm.es wrote in message ...

>it would be nice if I can write something like:
> int kk[] = {4, 0, 6};
> vector vx(kk);


You can come close using this:

// Use end(array) to get array.end()
template<class T, size_t I> static inline T* end(T (&array)[I])
{ return array + I; }

vector<int> vx(kk, end(kk));

If your compiler's optimization is good you can get the same behavior with
syntax like
  vector<int> vx(makevector(kk));
for an appropriate definition of makevector().

HTH
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ramon@nospam.jl1.quim.ucm.es
Date: 1999/02/10
Raw View

>C++ built-in arrays are deliberately intended to be compatible
>with arrays in C. In C, arrays are not first-class citizens,
>and have inconsistent behavior.

>If you don't want the annoying array behavior in C++, don't use
>C-style arrays. Use class vector or valarray, or write your
>own array class.

I am already using the class vector, but the way of initializing a vector
is rather weird:

#include <vector>

foo()
{
 int kk[] = {4, 0, 6};
 vector vx(3, kk);
 // work with vx
}


That is, I must evaluate by hand the number of elements (or use a macro, as
I am doing). You can say that this is syntax sugar, and you are right. But
it would be nice if I can write something like:

foo()
{
 int kk[] = {4, 0, 6};
 vector vx(kk);
 // work with vx
}

But I cannot define the neccesary constructor in the vector class (well,
I should use a different class since vector is standards) because of the
automatic conversion of arrays to pointers.

I believe that allowing me to use the number of elements of the array as
a template argument would not break any compatibility with C code, and it
would be useful for some cases like this when you work with an array whose
size is known at compile time.

Ramon



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Brian Parker" <bparker@uq.net.au>
Date: 1999/02/11
Raw View

ramon@nospam.jl1.quim.ucm.es wrote in message ...
>In standard C++, array arguments of functions are automatically converted
>to pointers. This feature is annoying under sometimes.

>...
>template<typename T>
>class my_vector {
>public:
> template<int n> my_vector(T x[n]) : storage(x), size(n) {}


If you pass a reference to an array then the conversion to pointer won't
happen i.e. change the line above to-

template<int n> my_vector(T (& x)[n]) : storage(x), size(n) {}

,Brian Parker
(bparker@uq.net.au)





[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@bardeen.ceg.uiuc.edu (Siemel Naran)
Date: 1999/02/11
Raw View
On 10 Feb 1999 22:21:27 GMT, ramon@nospam.jl1.quim.ucm.es

>foo()
>{
> int kk[] = {4, 0, 6};
> vector vx(3, kk);
> // work with vx
>}

It would be nice if builtin arrays had member functions 'size', 'begin',
'end', and 'value_type'.  Then you could say "kk.size()".  One problem
with this approach is that it suggests that kk.size() is a run-time
constant, whereas it is a compile-time integral constant.  In any case,
the syntax change is too radical, and probably won't happen.  However,
we can use sizeof to get the size of the array, and we can use the
array-to-pointer decay to simplify the notation.  Eg,

const char (&sizer(const T (&)[N]))[N]; // not implemented

void foo()
{
   const int kk[]={4,0,6};

   const size_t N=sizeof(kk)/sizeof(*kk); // or sizeof(sizer(kk))
      // same as
      // const size_t N=kk.size()
      // const size_t N=kk.capacity()

   std::copy(kk,kk+N,std::ostream_iterator<int>(" "));
      // same as
      // std::copy(kk.begin(),kk.end(),std::ostream_iterator<int>(" "));

   // but if we had the typeof operator, then we could go one step further
   std::copy(kk,kk+N,std::ostream_iterator<typeof(*kk)>(" "));

   // although we could use typedefs to achieve this too
   // but the extra typedef seems to clutter things up
   typedef int T;
   const T kkk[]={4,0,6};
   const size_t N=sizeof(sizer(kkk));
   std::copy(kkk,lkk+N,std::ostream_iterator<T>(" "));
}


If you don't need to take advantage of brace initialization -- and
to me, this seems to be most times, because you'll just initialize
all the elements to zero, or whatever -- then make a wrapper for
the builtin array:

template <class T, size_t N>
class fvector
{
   private:
      T d_data[N];

   public:
      typedef size_t    size_type     ;
      typedef T         value_type    ;
      typedef T       * iterator      ;
      typedef T const * const_iterator;

      fvector();
      reference operator[](size_type i) { return d_data[i]; }
};


--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Ram'on Garc'ia" <ramon@jl1.quim.ucm.es>
Date: 1999/02/11
Raw View
>If you pass a reference to an array then the conversion to pointer won't
>happen i.e. change the line above to-

>template<int n> my_vector(T (& x)[n]) : storage(x), size(n) {}

Thank you very much. This is exactly what I need. Also thanks to all
the other people that have replied.

Ramon
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ramon@nospam.jl1.quim.ucm.es
Date: 1999/02/08
Raw View
In standard C++, array arguments of functions are automatically converted
to pointers. This feature is annoying under sometimes.

Please forgive minor sintax errors and focus your comments in the real
problem.

For example:

template<typename T>
class my_vector {
public:
 template<int n> my_vector(T x[n]) : storage(x), size(n) {}
private:
 T *storage;
 size_t size;
};


void foo()
{
 int v[] = {2, 3, 4};
 my_vector mv(v);
 // Work with mv
}


At present, I workaround this limitation with a macro:

#define array_ws(x) sizeof(x)/sizeof(x[0]), x

So that my_vector has a constructor like

my_vector(size_t n, T* x): size(n), storage(x) {}

that is used in this way:

my_vector mv(array_ws(v));



Best regards,
 Ramon
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Charles Chen <charles@sapphire-it.demon.co.uk>
Date: 1999/02/10
Raw View
Is there any reason why you did not choose to use STL vector, which is
part of C++ standard?

Charles

In article <m0ww1stvzk.fsf@jl1.quim.ucm.es>,
ramon@nospam.jl1.quim.ucm.es writes
>In standard C++, array arguments of functions are automatically converted
>to pointers. This feature is annoying under sometimes.
>
>Please forgive minor sintax errors and focus your comments in the real
>problem.
>
>For example:
>
>template<typename T>
>class my_vector {
>public:
>       template<int n> my_vector(T x[n]) : storage(x), size(n) {}
>private:
>       T *storage;
>       size_t size;
>};
>
>
>void foo()
>{
>       int v[] = {2, 3, 4};
>       my_vector mv(v);
>       // Work with mv
>}
>
>
>At present, I workaround this limitation with a macro:
>
>#define array_ws(x) sizeof(x)/sizeof(x[0]), x
>
>So that my_vector has a constructor like
>
>my_vector(size_t n, T* x): size(n), storage(x) {}
>
>that is used in this way:
>
>my_vector mv(array_ws(v));

--
Charles Chen
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1999/02/10
Raw View
ramon@nospam.jl1.quim.ucm.es writes:

>In standard C++, array arguments of functions are automatically converted
>to pointers. This feature is annoying under sometimes.

C++ built-in arrays are deliberately intended to be compatible
with arrays in C. In C, arrays are not first-class citizens,
and have inconsistent behavior.

If you don't want the annoying array behavior in C++, don't use
C-style arrays. Use class vector or valarray, or write your
own array class.


--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]