 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Dhruv Guest
|
Posted: Mon Oct 13, 2003 8:39 pm Post subject: vector constructors [was: realloc in c++] |
|
|
<BEGIN QUOTED TEXT>
| Quote: | Hold on, I'm unconvinced again. Where did that (int, int) constructor
for vector<vector come from?
|
It comes from the template constructor
template<typename InputIterator>
vector(InputIterator first, InputIterator last);
which provides a best-match specialization
| Quote: | It works in the first compiler I
tried, but I that;'s because it's matching
vector(
size_type _Count,
const Type& _Val
);
|
No, this constructor cannot be used because in this case Type is
vector<int> and the constructor that could be called with a single
integer argument (to make the conversion) is explicit as you said.
That is why I remarked in my previous message that the above construct
creates no supererogatory temporaries.
| Quote: | and the second integer is matching
vector(
size_type _Count
);
to do a cast from int to vector<int>. But the second compiler I tried
doesn't have that latter constructor. Instead it has
explicit vector(
size_type _Count
);
|
yes, this constructor is conforming.
| Quote: | and sure enough your suggestion doesn't compile, because it can't do
the default conversion from int to vector<int>.
|
Upgrade your compiler or library :-)
Here is an explanation of why your compiler should accept the
construct
vector<vector matrix(3, 3);
The arguments used in the object "matrix" construction are all the
same. Therefore, overload resolution selects the specialization of
the template constructor mentioned above (with InputIterator = int).
Now, there is an apparent embarassment because "int" is not an
iterator. The standard library requires (see 23.1.1/9) that, in such
situations, that instantiation should behave as if I wrote
vector<vector matrix(vector<vector::size_type(3),
static_cast<vector(3));
As you can se, the static_cast<> bypasses the "explicit"ness
# explicit vector(
# size_type _Count
# );
<END QUOTED TEXT>
Now, my point is that the explicit was meant to be there to stop this kind
of usage of the vector's constructor, and that's what being done here:
Automatic conversion (unknown to the user), but using static_cast<>. Now,
doesn't this seem wierd:
1. Stuff like vector<vector vv (3, 3);
Will work fine, and so will:
vv.insert (vv.begin(), 3, 3);
But, this will not:
vv.insert (vv.begin (), 3);
and neither will this:
vv.push_back (3);
It seems a bit counter intuitive to me....... The reason for this (I guess
is because all implementations are passing the iterators around by value,
which is quite correct, but in the dispatch constructor, where they detect
the 2nd type as an integer, again, values are being passed around by
value, and also their type (template parameters for the dispatch routine)
is being deduced using the type of parameter, instead of keeping the 2nd
type as const_reference.] If this is done, I guess these kind of
constructs will also be avoided.......
So, in the libstdc++ that I have, replace:
_M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val,
__true_type)
BY:
_M_insert_dispatch(iterator __pos, _Integer __n, const_reference __val,
__true_type)
And the same thing for the constructor.......
Regards,
-Dhruv.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Tue Oct 14, 2003 8:42 am Post subject: Re: vector constructors [was: realloc in c++] |
|
|
"Dhruv" <dhruvbird (AT) gmx (DOT) net> writes:
[...]
| Quote: | Now, my point is that the explicit was meant to be there to stop this kind
of usage of the vector's constructor, and that's what being done here:
Automatic conversion (unknown to the user), but using
static_cast<>.
|
That is an issue I'm ambivalent about. See page 9 of the set of
slides of a talk I gave at the ACCU Spring Conference 2002
http://www.cmla.ens-cachan.fr/~dosreis/C++/talks/generic-programming-in-cxx.pdf
| Quote: | Now, doesn't this seem wierd:
|
"weird"? I don't know. Certainly irregular and probably counter-intuitive.
| Quote: | 1. Stuff like vector<vector vv (3, 3);
Will work fine, and so will:
vv.insert (vv.begin(), 3, 3);
But, this will not:
vv.insert (vv.begin (), 3);
and neither will this:
vv.push_back (3);
It seems a bit counter intuitive to me....... The reason for this (I guess
is because all implementations are passing the iterators around by value,
which is quite correct, but in the dispatch constructor, where they detect
the 2nd type as an integer, again, values are being passed around by
value, and also their type (template parameters for the dispatch routine)
is being deduced using the type of parameter, instead of keeping the 2nd
type as const_reference.] If this is done, I guess these kind of
constructs will also be avoided.......
|
but then, they would not implement the requirements of the standard
library. Was that behaviour intended? I'm almost certain it was an
oversight. On the other hand, it does has some virtue. So, it is
kind of half-full or half-empty.
--
Gabriel Dos Reis
[email]gdr (AT) integrable-solutions (DOT) net[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Howard Hinnant Guest
|
Posted: Tue Oct 14, 2003 9:09 am Post subject: Re: vector constructors [was: realloc in c++] |
|
|
In article <pan.2003.10.13.14.19.58.901014 (AT) gmx (DOT) net>,
"Dhruv" <dhruvbird (AT) gmx (DOT) net> wrote:
| Quote: | Here is an explanation of why your compiler should accept the
construct
vector<vector matrix(3, 3);
The arguments used in the object "matrix" construction are all the
same. Therefore, overload resolution selects the specialization of
the template constructor mentioned above (with InputIterator = int).
Now, there is an apparent embarassment because "int" is not an
iterator. The standard library requires (see 23.1.1/9) that, in such
situations, that instantiation should behave as if I wrote
vector<vector matrix(vector<vector::size_type(3),
static_cast<vector(3));
As you can se, the static_cast<> bypasses the "explicit"ness
# explicit vector(
# size_type _Count
# );
|
I am not convinced that:
vector<vector matrix(3, 3);
must work.
The standard says that *if* InputIterator is an integral type, then do
the static_cast dance. The standard does not say that matrix(3, 3)
/must/ bind to the templated constructor.
Using the restricted template technique (restrict_to / enable_if), one
can prevent the templated constructor from being bound by matrix(3, 3).
Instead matrix(3, 3) will attempt to bind to the size/value constructor,
but fail because 3 won't implicitly convert to a vector<double>.
-Howard
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Tue Oct 14, 2003 8:53 pm Post subject: Re: vector constructors [was: realloc in c++] |
|
|
Howard Hinnant <hinnant (AT) metrowerks (DOT) com> writes:
| Quote: | In article <pan.2003.10.13.14.19.58.901014 (AT) gmx (DOT) net>,
"Dhruv" <dhruvbird (AT) gmx (DOT) net> wrote:
Here is an explanation of why your compiler should accept the
construct
vector<vector matrix(3, 3);
The arguments used in the object "matrix" construction are all the
same. Therefore, overload resolution selects the specialization of
the template constructor mentioned above (with InputIterator = int).
Now, there is an apparent embarassment because "int" is not an
iterator. The standard library requires (see 23.1.1/9) that, in such
situations, that instantiation should behave as if I wrote
vector<vector matrix(vector<vector::size_type(3),
static_cast<vector(3));
As you can se, the static_cast<> bypasses the "explicit"ness
# explicit vector(
# size_type _Count
# );
I am not convinced that:
vector<vector matrix(3, 3);
must work.
|
It must work. An implementation that rejects it is bogus on that
respect. See below.
| Quote: | The standard says that *if* InputIterator is an integral type, then do
the static_cast dance. The standard does not say that matrix(3, 3)
/must/ bind to the templated constructor.
|
Detailed transscript of why the templated constructor must be selected.
The set of candidate vector<double> constructors is:
(1) explicit vector(const Allocator& = Allocator());
(2) explicit vector(size_type, const double& = double(),
const Allocator& = Allocator());
(3) template<InputIteraror>
vector(InputIterator first, InputIterator last,
const Allocator& = Allocator());
(4) vector(const vector<double, Allocator>&);
The constructor (3) being a template, 14.8.3/1 applies. In particular
given the call-arguments (3, 3), the template argument deduction and
checking succeeds and deduce InputIterator = int.
For each function template, if the argument deduction and checking
succeeds, the template-arguments (deduced and/or explicit) are used
to instantiate a single function template specialization which is
added to the candidate functions set to be used in overload
resolution. If, for a given function template, argument deduction
fails, no such function is added to the set of candidate functions
for that template. The complete set of candidate functions includes
all the function templates instantiated in this way and all of the
non-template overloaded functions of the same name. The function
template specializations are treated like any other functions in
the remainder of overload resolution, except as explicitly noted in
13.3.3.
I'll number that specialization (3').
According to 13.3/3
-- First, a subset of the candidate functions -- those that have the
proper number of arguments and meet certain other conditions -- is
selected to form a set of viable functions (13.3.2).
-- Then the best viable function is selected based on the implicit
conversion sequences (13.3.3.1) needed to match each argument to
the corresponding paramter of each viable function.
According to 13.3.2/2, the constructors (1) and (4) are not viable
functions because they do not have enough parameters.
Paragraph 13.3.2/3 tells us that constructor (2) is not viable.
So, we're left with (3'), which by definition already provides a best
match. In conclusion, Overload Resolution effectively selects the
templated constructor.
The rest follows from the library special disposition.
| Quote: | Using the restricted template technique (restrict_to / enable_if), one
can prevent the templated constructor from being bound by matrix(3, 3).
Instead matrix(3, 3) will attempt to bind to the size/value constructor,
but fail because 3 won't implicitly convert to a vector<double>.
|
No. See above. The only thing that is taken into account in overload
resolution is the function signature. Whether you use enable_if or
restrict_to is immaterial -- at least, if you use it in a conforming
way. I've heard of some implementations that have modified the
template constructors signature in a non conforming way.
-- Gaby
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dhruv Guest
|
Posted: Tue Oct 14, 2003 9:09 pm Post subject: Re: vector constructors [was: realloc in c++] |
|
|
On Tue, 14 Oct 2003 05:09:51 -0400, Howard Hinnant wrote:
| Quote: | In article <pan.2003.10.13.14.19.58.901014 (AT) gmx (DOT) net>,
"Dhruv" <dhruvbird (AT) gmx (DOT) net> wrote:
Here is an explanation of why your compiler should accept the
construct
vector<vector matrix(3, 3);
The arguments used in the object "matrix" construction are all the
same. Therefore, overload resolution selects the specialization of
the template constructor mentioned above (with InputIterator = int).
Now, there is an apparent embarassment because "int" is not an
iterator. The standard library requires (see 23.1.1/9) that, in such
situations, that instantiation should behave as if I wrote
vector<vector matrix(vector<vector::size_type(3),
static_cast<vector(3));
As you can se, the static_cast<> bypasses the "explicit"ness
# explicit vector(
# size_type _Count
# );
I am not convinced that:
vector<vector matrix(3, 3);
must work.
The standard says that *if* InputIterator is an integral type, then do
the static_cast dance. The standard does not say that matrix(3, 3)
/must/ bind to the templated constructor.
Using the restricted template technique (restrict_to / enable_if), one
can prevent the templated constructor from being bound by matrix(3, 3).
Instead matrix(3, 3) will attempt to bind to the size/value constructor,
but fail because 3 won't implicitly convert to a vector<double>.
|
I have a couble of questions:
1. What is the restricted template technique?
2. And, how would you use it to prevent the construct under question from
binding to the templated constructor.
3. AFAICS, matrix (3, 3) will *have* to bind to either:
a. InputIterator, InputIterator, OR:
b. std::size_type, int.
And, here (a) is a better match, so it will be selected, and then the
dispatch tricks on the type of InputIterator come into play. Can you
suggest a different course of action?
Regards,
-Dhruv.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Howard Hinnant Guest
|
Posted: Wed Oct 15, 2003 10:41 am Post subject: Re: vector constructors [was: realloc in c++] |
|
|
In article <flbrskjc5i.fsf (AT) sel (DOT) cmla.ens-cachan.fr>,
Gabriel Dos Reis <dosreis (AT) cmla (DOT) ens-cachan.fr> wrote:
| Quote: | | Using the restricted template technique (restrict_to / enable_if), one
| can prevent the templated constructor from being bound by matrix(3, 3).
| Instead matrix(3, 3) will attempt to bind to the size/value constructor,
| but fail because 3 won't implicitly convert to a vector<double>.
No. See above. The only thing that is taken into account in overload
resolution is the function signature. Whether you use enable_if or
restrict_to is immaterial -- at least, if you use it in a conforming
way. I've heard of some implementations that have modified the
template constructors signature in a non conforming way.
|
Defaulted arguments can be added to any non-virtual member:
17.4.4.4/2.
-Howard
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Howard Hinnant Guest
|
Posted: Wed Oct 15, 2003 4:19 pm Post subject: Re: vector constructors [was: realloc in c++] |
|
|
In article <pan.2003.10.14.13.29.21.78977 (AT) gmx (DOT) net>,
"Dhruv" <dhruvbird (AT) gmx (DOT) net> wrote:
| Quote: | I have a couble of questions:
1. What is the restricted template technique?
|
See:
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=11032003100616005
4%25hinnant%40metrowerks.com&rnum=2
for details.
| Quote: | 2. And, how would you use it to prevent the construct under question from
binding to the templated constructor.
|
template <class InputIterator>
vector(InputIterator first, InputIterator last,
typename restrict_to<!is_integral::type* = 0);
template <class InputIterator>
vector(InputIterator first, InputIterator last, const Allocator&,
typename restrict_to<!is_integral::type* = 0);
-Howard
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Wed Oct 15, 2003 10:07 pm Post subject: Re: vector constructors [was: realloc in c++] |
|
|
Howard Hinnant <hinnant (AT) metrowerks (DOT) com> writes:
| Quote: | In article <flbrskjc5i.fsf (AT) sel (DOT) cmla.ens-cachan.fr>,
Gabriel Dos Reis <dosreis (AT) cmla (DOT) ens-cachan.fr> wrote:
| Using the restricted template technique (restrict_to / enable_if), one
| can prevent the templated constructor from being bound by matrix(3, 3).
| Instead matrix(3, 3) will attempt to bind to the size/value constructor,
| but fail because 3 won't implicitly convert to a vector<double>.
No. See above. The only thing that is taken into account in overload
resolution is the function signature. Whether you use enable_if or
restrict_to is immaterial -- at least, if you use it in a conforming
way. I've heard of some implementations that have modified the
template constructors signature in a non conforming way.
Defaulted arguments can be added to any non-virtual member:
17.4.4.4/2.
|
That section is *no* permission for an implementation to transmute the
observable standard behaviour of a call that corresponds to the
non-transmoglified standard signature.
In short, an implememtation that rejects matrix(3, 3) is just buggy.
-- Gaby
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Thu Oct 16, 2003 2:07 pm Post subject: Re: vector constructors [was: realloc in c++] |
|
|
Howard Hinnant <hinnant (AT) metrowerks (DOT) com> writes:
[...]
| Quote: | 2. And, how would you use it to prevent the construct under question from
binding to the templated constructor.
template <class InputIterator
vector(InputIterator first, InputIterator last,
typename restrict_to::type* = 0);
|
This is not conforming. You're free to add defaulted arguments. But
you're not allowed to transmute semantics.
I had this discussion with Doug on the GNU list and he agrees the
above is deviating -- although he seemed to be surprised on first
sight.
--
Gabriel Dos Reis
[email]gdr (AT) integrable-solutions (DOT) net[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Howard Hinnant Guest
|
Posted: Thu Oct 16, 2003 2:18 pm Post subject: Re: vector constructors [was: realloc in c++] |
|
|
In article <flekxe20vn.fsf (AT) sel (DOT) cmla.ens-cachan.fr>,
Gabriel Dos Reis <dosreis (AT) cmla (DOT) ens-cachan.fr> wrote:
| Quote: | In short, an implememtation that rejects matrix(3, 3) is just buggy.
|
23.1.1/11:
| Quote: | One way that sequence implementors can satisfy this requirement is to
specialize the member template for every integral type.
|
Indeed, this is the only implementation technique for paragraphs 9-11
that is specifically mentioned to conform.
Using this suggestion (which the standard specifically says conforms),
would lead to something along the lines of (simplified of course):
template <class T>
struct vector
{
typedef unsigned size_type;
explicit vector(size_type) {}
vector(size_type, const T&) {}
template <class I>
vector(I, I);
// ...
};
template <class T>
template <class I>
vector<T>::vector(I, I)
{
// ...
}
template <>
template <>
vector<int>::vector(int, int)
{
// ...
}
template <>
template <>
vector<int>::vector(unsigned, unsigned)
{
// ...
}
// ...
template <>
template <>
vector<unsigned>::vector(int, int)
{
// ...
}
template <>
template <>
vector<unsigned>::vector(unsigned, unsigned)
{
// ...
}
// ...
Now when you say:
vector<int> v(10, 1);
The int specialization of the member template is bound to, which will
have the same logic as the size/value constructor, just as the standard
says.
But note that there is no member template specialization that looks like:
template <class T>
template <>
vector<T>::vector(int, int)
{
// ...
}
Such a specialization is illegal (14.7.3/1 . And surely 23.1.1/11 is
not suggesting an illegal implementation. And yet:
vector<vector v(3, 3);
still attempts to bind to the unspecialized member template, and thus
will not compile for the example implementation given by 23.1.1/11, the
very implementation mentioned as conforming!
Because of the impossiblity of specializing member templates with a
non-specialized outer template, it seems clear that 23.1.1/11 is
addressing only sequences of integral types. How else could the
suggested implementation technique ever work?!
It is simply because of an implementation technique that you are
familiar with that vector<vector v(3, 3); compiles. Your
implementaiton technique is not blessed by the standard. Although I
will stop short (far short) of calling it non-conforming.
The expression:
vector<vector v(3, 3);
was never intended to compile. And I don't see wording in the standard
that even accidently says it must. If you catch this call with the
member template constructor and then forward it along to the size/value
logic under the hood, the call works. But if the implementation is
designed to never allow integral types to bind to the member template in
the first place, then v(3, 3) fails. The standard specifically mentions
one technique in the latter category. Restricting templates is another
such technique. And neither is "just buggy."
-Howard
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Peter Dimov Guest
|
Posted: Thu Oct 16, 2003 2:54 pm Post subject: Re: vector constructors [was: realloc in c++] |
|
|
Gabriel Dos Reis <dosreis (AT) cmla (DOT) ens-cachan.fr> wrote
| Quote: | Howard Hinnant <hinnant (AT) metrowerks (DOT) com> writes:
| In article <flbrskjc5i.fsf (AT) sel (DOT) cmla.ens-cachan.fr>,
| Gabriel Dos Reis <dosreis (AT) cmla (DOT) ens-cachan.fr> wrote:
|
| > | Using the restricted template technique (restrict_to /
enable_if), one
| > | can prevent the templated constructor from being bound by
matrix(3, 3).
| > | Instead matrix(3, 3) will attempt to bind to the size/value
constructor,
| > | but fail because 3 won't implicitly convert to a
vector<double>.
|
| > No. See above. The only thing that is taken into account in
overload
| > resolution is the function signature. Whether you use enable_if
or
| > restrict_to is immaterial -- at least, if you use it in a
conforming
| > way. I've heard of some implementations that have modified the
| > template constructors signature in a non conforming way.
|
| Defaulted arguments can be added to any non-virtual member:
|
| 17.4.4.4/2.
That section is *no* permission for an implementation to transmute the
observable standard behaviour of a call that corresponds to the
non-transmoglified standard signature.
In short, an implememtation that rejects matrix(3, 3) is just buggy.
|
I don't agree. The intent of the standard is that the constructor
template <class InputIterator>
container(InputIterator first, InputIterator last,
const Allocator& = Allocator());
should not interfere with calls to
explicit container(size_type n, const T& value = T(),
const Allocator& = Allocator());
The letter of the standard can indeed be interpreted to support your
claim, which I believe is a defect in the standard.
matrix(3, 3) is not the correct way to invoke the size_type/value_type
constructor, "by design". There is no good reason (design reason,
strict conformance aside for a moment) for the InputIterator
constructor to suddenly turn it into a valid call.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dhruv Guest
|
Posted: Fri Oct 17, 2003 11:44 am Post subject: Re: vector constructors [was: realloc in c++] |
|
|
On Thu, 16 Oct 2003 10:07:49 -0400, Gabriel Dos Reis wrote:
| Quote: | Howard Hinnant <hinnant (AT) metrowerks (DOT) com> writes:
[...]
| > 2. And, how would you use it to prevent the construct under question from
| > binding to the templated constructor.
|
| template <class InputIterator
| vector(InputIterator first, InputIterator last,
| typename restrict_to::type* = 0);
This is not conforming. You're free to add defaulted arguments. But
you're not allowed to transmute semantics.
I had this discussion with Doug on the GNU list and he agrees the
above is deviating -- although he seemed to be surprised on first
sight.
|
Standards aside, the above construct does not seem to obey explicit, it's
as simple as that, and so it must and should fail, but it doesn't on the
current libstdc++ implementation. This currently means that a vector is
being constructed form the integer 3, without the user having explicitly
having said so...
Regards,
-Dhruv.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Sat Oct 18, 2003 10:11 pm Post subject: Re: vector constructors [was: realloc in c++] |
|
|
Howard Hinnant <hinnant (AT) metrowerks (DOT) com> writes:
| Quote: | In article <flekxe20vn.fsf (AT) sel (DOT) cmla.ens-cachan.fr>,
Gabriel Dos Reis <dosreis (AT) cmla (DOT) ens-cachan.fr> wrote:
In short, an implememtation that rejects matrix(3, 3) is just buggy.
23.1.1/11:
One way that sequence implementors can satisfy this requirement is to
specialize the member template for every integral type.
|
That is a note (so non-normative) *and* it is buggy. I've already
point out that bug note several times in the past.
| Quote: | Indeed, this is the only implementation technique for paragraphs 9-11
that is specifically mentioned to conform.
|
You're taking a buggy note to be a conforming requirement. Ahem.
[...]
| Quote: | It is simply because of an implementation technique that you are
familiar with that vector<vector v(3, 3); compiles. Your
|
No. That "vector<vector v(3, 3)" is well-formed follows from a
clear sequence of logical deductions. I've already shown that
step-by-step. You snipped that evidence, in favor of buggy
non-normative note. Can you go back and point out exactly where in the
sequence of steps I showed, there is anything thyat says it should not
compile?
| Quote: | implementaiton technique is not blessed by the standard. Although I
will stop short (far short) of calling it non-conforming.
The expression:
vector<vector v(3, 3);
was never intended to compile.
|
That _might_ not be intended. But the current wording says different.
If an implementation rejects that, that implementation does not
conform to the standard specification.
| Quote: | And I don't see wording in the standard
that even accidently says it must.
|
Sure there is. Just follow the process of overload resolution.
It can't be otherwise.
| Quote: | If you catch this call with the
member template constructor and then forward it along to the size/value
logic under the hood, the call works. But if the implementation is
designed to never allow integral types to bind to the member template in
the first place, then v(3, 3) fails.
|
If the implementation is designed that way, that implementation is
simply buggy. I've exhibited logical steps of why.
--
Gabriel Dos Reis
[email]gdr (AT) integrable-solutions (DOT) net[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Sat Oct 18, 2003 10:13 pm Post subject: Re: vector constructors [was: realloc in c++] |
|
|
[email]pdimov (AT) mmltd (DOT) net[/email] (Peter Dimov) writes:
| Quote: | Gabriel Dos Reis <dosreis (AT) cmla (DOT) ens-cachan.fr> wrote in message
news:<flekxe20vn.fsf (AT) sel (DOT) cmla.ens-cachan.fr>...
Howard Hinnant <hinnant (AT) metrowerks (DOT) com> writes:
| In article <flbrskjc5i.fsf (AT) sel (DOT) cmla.ens-cachan.fr>,
| Gabriel Dos Reis <dosreis (AT) cmla (DOT) ens-cachan.fr> wrote:
|
| > | Using the restricted template technique (restrict_to /
enable_if), one
| > | can prevent the templated constructor from being bound by
matrix(3, 3).
| > | Instead matrix(3, 3) will attempt to bind to the size/value
constructor,
| > | but fail because 3 won't implicitly convert to a
vector<double>.
|
| > No. See above. The only thing that is taken into account in
overload
| > resolution is the function signature. Whether you use enable_if
or
| > restrict_to is immaterial -- at least, if you use it in a
conforming
| > way. I've heard of some implementations that have modified the
| > template constructors signature in a non conforming way.
|
| Defaulted arguments can be added to any non-virtual member:
|
| 17.4.4.4/2.
That section is *no* permission for an implementation to transmute the
observable standard behaviour of a call that corresponds to the
non-transmoglified standard signature.
In short, an implememtation that rejects matrix(3, 3) is just buggy.
I don't agree.
|
You're welcome :-)
| Quote: | The intent of the standard is that the constructor
template
container(InputIterator first, InputIterator last,
const Allocator& = Allocator());
should not interfere with calls to
explicit container(size_type n, const T& value = T(),
const Allocator& = Allocator());
|
There is the intent *and* there is what is specified. What is
specified clearly does not support the enable_if transmutation Howard
is advocating.
| Quote: | The letter of the standard can indeed be interpreted to support your
claim, which I believe is a defect in the standard.
|
Not just it can be interpreted that way, but that is the only
interpretation. The constructor is called *after* overload resolution.
And the information in place for overload resolution *cannot* select
something else. Can you show where in the overload resolution
process, it could have chosen somethinng else, given the standard
signature?
| Quote: | matrix(3, 3) is not the correct way to invoke the size_type/value_type
constructor, "by design". There is no good reason (design reason,
strict conformance aside for a moment) for the InputIterator
constructor to suddenly turn it into a valid call.
|
Yet that is what the requiremnt says.
--
Gabriel Dos Reis
[email]gdr (AT) integrable-solutions (DOT) net[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gabriel Dos Reis Guest
|
Posted: Sat Oct 18, 2003 10:14 pm Post subject: Re: vector constructors [was: realloc in c++] |
|
|
"Dhruv" <dhruvbird (AT) gmx (DOT) net> writes:
| Quote: | On Thu, 16 Oct 2003 10:07:49 -0400, Gabriel Dos Reis wrote:
Howard Hinnant <hinnant (AT) metrowerks (DOT) com> writes:
[...]
| > 2. And, how would you use it to prevent the construct under question from
| > binding to the templated constructor.
|
| template <class InputIterator
| vector(InputIterator first, InputIterator last,
| typename restrict_to::type* = 0);
This is not conforming. You're free to add defaulted arguments. But
you're not allowed to transmute semantics.
I had this discussion with Doug on the GNU list and he agrees the
above is deviating -- although he seemed to be surprised on first
sight.
Standards aside, the above construct does not seem to obey explicit, it's
as simple as that, and so it must and should fail, but it doesn't on the
|
Reasonable people may disagree on this.
| Quote: | current libstdc++ implementation. This currently means that a vector is
being constructed form the integer 3, without the user having explicitly
having said so...
|
Yes. That was never hidden.
--
Gabriel Dos Reis
[email]gdr (AT) integrable-solutions (DOT) net[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|