Topic: Using vector of vectors
Author: "E. Robert Tisdale" <E.Robert.Tisdale@jpl.nasa.gov>
Date: 22 Jun 2002 00:35:36 GMT Raw View
John Potter wrote:
> E. Robert Tisdale wrote:
>
> > aran@100acres.ws wrote:
> >
> > > E. Robert Tisdale wrote:
> > >
> > > > const
> > > > int N = 4;
> > > > const
> > > > int C = 3;
> > > > using std::vector;
> > > > vector<vector<double> > distanze(N, C);
> > > >
> > > > Did you get different results from your compiler?
> > >
> > > Yes.
>
> Your compiler is broken.
>
> > > You are depending on a missing explicit in your stl code. Your
> > >
> > > vector<vector<double> > distanze(N, C);
>
> No. Your compiler is likely missing member template support or
> your library was written under that assumption. That statement matches
>
> template <class InputIterator>
> vector<vector<double> > (InputIterator N, InputIterator C)
>
> Overload resolution is totally ignorant of the intent of InputIterator.
> Two ints matches. Since this problem was well known,
> 23.1.1/9 requires that
> when InputIterator is an integral type that it behave as
>
> vector<vector<double> > (static_cast<size_type>(N),
> static_cast<vector<double> >(C));
>
> The static_cast makes the value_type construction explicit.
James Kanze wrote:
> aran@100acres.ws wrote:
>
> > E. Robert Tisdale wrote:
> >
> > > aran@100acres.ws wrote:
> > >
> > > > E. Robert Tisdale wrote:
> > > >
> > > > > Did you get different results from your compiler?
> > > >
> > > > Yes.
> > > >
> > > > You are depending on a missing explicit in your stl code. Your
> > > >
> > > > vector<vector<double> > distanze(N, C);
> > > >
> > > > is being automatically converted to
> > > >
> > > > vector<vector<double> > distanze(N, vector<double>(C));
> > > >
> > > > by the compiler.
> > > > That constructor should be explicit and apparently is not in your
library.
> > > >
> > > > (see 23.2.4.2 of the 1998 C++ spec)
> > >
> > > In /usr/include/g++-v3/bits/stl_vector.h
> > >
> > > template <class _Tp, class _Alloc = allocator<_Tp> >
> > > class vector : protected _Vector_base<_Tp, _Alloc> {
> > > // [snip]
> > > public:
> > > // [snip]
> > > explicit vector(size_type __n): _Base(__n, allocator_type())
{
> > > _M_finish = uninitialized_fill_n(_M_start, __n, _Tp());
> > > }
> > > // [snip]
> > > };
> >
> > Wow, you're right.
> > I checked this at work (we're using g++)
> > and the constructor that gets called is:
> >
> > template <class Iterator>
> > vector(Iterator b, Iterator e);
>
> Which is as it should be. See 23.1.1/9.
>
> On the other hand,
> I (and I suspect some others) don't like the fact that
> this clause hides a static_cast, which in turn "undoes" an "explicit".
> Ideally, we'd like it to act as if there was
> an attempt to call the (size_t,T const&) constructor.
>
> > There is a special check in the g++ library
> > if Iterator is an integral type to explicitly construct the contained
type.
> >
> > This is by no means a standard feature of standard STL
> > (i.e. non-portable). It's actually some interesting code.
>
> The trick is interesting. But it is quite standard
> and required for a library to be conforming.
So who is correct here? John Potter? Or James Kanze?
Is my GNU C++ compiler [standard library] correct?
Or should I file a bug report?
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: Sun, 23 Jun 2002 21:24:53 CST Raw View
On 22 Jun 2002 00:35:36 GMT, "E. Robert Tisdale"
<E.Robert.Tisdale@jpl.nasa.gov> wrote:
> John Potter wrote:
> > E. Robert Tisdale wrote:
> > > aran@100acres.ws wrote:
> > > > E. Robert Tisdale wrote:
> > > > > Did you get different results from your compiler?
> > > > Yes.
> > Your compiler is broken.
Note that it is aran's compiler that is broken.
> So who is correct here? John Potter? Or James Kanze?
Since we agree, that is easy. :)
> Is my GNU C++ compiler [standard library] correct?
The library is correct.
Here is a simple case which might help to see why it is needed.
vector<int> v(5, 7);
The (iter, iter) ctor wins over the (size_type, int) ctor. We would
not want this to fail. This would work with only one static_cast.
vector<int> v(vector<int>::size_type(5), 7);
Solves the problem, but is at least awkward.
vector<double> v(5, 7);
Again, the (iter, iter) ctor and something must be cast.
vector<double> v(5, 7.);
Solves the problem, and is not too bad. If the special rule
were not there, the error message from the missing period should
be stressful for a beginner.
The fact that it works in the two dimensional case may be an accident
and it does not extend to three dimensions.
vector<double, vector<double> > v(5, vector<double>(7));
Solves the problem, and seems appropriate to me.
John
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: Thu, 20 Jun 2002 23:12:19 GMT Raw View
On Thu, 20 Jun 2002 17:26:56 GMT, "E. Robert Tisdale"
<E.Robert.Tisdale@jpl.nasa.gov> wrote:
> aran@100acres.ws wrote:
> > "E. Robert Tisdale" <E.Robert.Tisdale@jpl.nasa.gov> writes:
> > > const
> > > int N = 4;
> > > const
> > > int C = 3;
> > > using std::vector;
> > > vector<vector<double> > distanze(N, C);
> > > Did you get different results from your compiler?
> > Yes.
Your compiler is broken.
> > You are depending on a missing explicit in your stl code. Your
> >
> > vector<vector<double> > distanze(N, C);
No. Your compiler is likely missing member template support or your
library was written under that assumption. That statement matches
template <class InputIterator>
vector<vector<double> > (InputIterator N, InputIterator C)
Overload resolution is totally ignorant of the intent of
InputIterator. Two ints matches. Since this problem was well known,
23.1.1/9 requires that when InputIterator is an integral type that it
behave as
vector<vector<double> > (static_cast<size_type>(N),
static_cast<vector<double> >(C));
The static_cast makes the value_type construction explicit.
John
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "E. Robert Tisdale" <E.Robert.Tisdale@jpl.nasa.gov>
Date: Thu, 20 Jun 2002 17:26:56 GMT Raw View
aran@100acres.ws wrote:
> "E. Robert Tisdale" <E.Robert.Tisdale@jpl.nasa.gov> writes:
>
> > John Harrison wrote:
> >
> > > I think you mean
> > >
> > > vector<vector<double> > distanze(N, vector<double>(C));
> >
> > Nope.
> >
> > $ cat main.cc
> > #include<iostream>
> > #include<iomanip>
> > #include<vector>
> >
> > int
> > main(int argc, char* argv[]) {
> > const
> > int N = 4;
> > const
> > int C = 3;
> > using std::vector;
> > vector<vector<double> > distanze(N, C);
> >
> > for (int j = 0; j < N; ++j)
> > for (int k = 0; k < C; ++k)
> > distanze[j][k] = k + j*10;
> >
> > std::cout << "distanze =" << std::endl;
> > for (int j = 0; j < N; ++j) {
> > for (int k = 0; k < C; ++k)
> > std::cout << ' ' << std::setw(2) << distanze[j][k];
> > std::cout << std::endl;
> > }
> > return 0;
> > }
> >
> > $ g++ -O2 -ansi -pedantic -Wall -o main main.cc
> > $ ./main
> > distanze =
> > 0 1 2
> > 10 11 12
> > 20 21 22
> > 30 31 32
> >
> > Did you get different results from your compiler?
>
> Yes.
>
> You are depending on a missing explicit in your stl code. Your
>
> vector<vector<double> > distanze(N, C);
>
> is being automatically converted to
>
> vector<vector<double> > distanze(N, vector<double>(C) );
>
> by the compiler.
> That constructor should be explicit and aparently is not in your library.
>
> (see 23.2.4.2 of the 1998 C++ spec)
In /usr/include/g++-v3/bits/stl_vector.h
template <class _Tp, class _Alloc = allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc> {
// [snip]
public:
// [snip]
explicit vector(size_type __n): _Base(__n, allocator_type()) {
_M_finish = uninitialized_fill_n(_M_start, __n, _Tp());
}
// [snip]
};
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]