Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Are additional constructors for standard containers allowed?

Reply
Thread Tools

Are additional constructors for standard containers allowed?

 
 
Alf P. Steinbach /Usenet
Guest
Posts: n/a
 
      09-03-2010
With MSVC 10.0

std::bitset<32>( 666u )

does not compile. Apparently due to an extra constructor taking 'int' argument.
Is that allowed by the standard?



Cheers,

- Alf

--
blog at <url: http://alfps.wordpress.com>
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      09-03-2010
On 9/3/2010 7:37 AM, Alf P. Steinbach /Usenet wrote:
> With MSVC 10.0
>
> std::bitset<32>( 666u )
>
> does not compile. Apparently due to an extra constructor taking 'int'
> argument. Is that allowed by the standard?


I haven't found any wording in the Standard *prohibiting* any C++
Standard Library implementor from supplying more functionality than
specified in the Standard, like more c-tors, extra member functions,
etc. Of course, if code that would otherwise be legal becomes
ill-formed when those new parts are added, it becomes QoI issue.
Complain to the vendor.

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
 
 
 
Johannes Schaub (litb)
Guest
Posts: n/a
 
      09-03-2010
Alf P. Steinbach /Usenet wrote:

> With MSVC 10.0
>
> std::bitset<32>( 666u )
>
> does not compile. Apparently due to an extra constructor taking 'int'
> argument. Is that allowed by the standard?
>


Just like adding template parameters to a template is disallowed (even if
all of them have defaults) because it makes valid code invalid, this one
would be invalid aswell, i think. Haven't got any chap/verse though.
 
Reply With Quote
 
Michael Doubez
Guest
Posts: n/a
 
      09-03-2010
On 3 sep, 16:29, Victor Bazarov <(E-Mail Removed)> wrote:
> On 9/3/2010 7:37 AM, Alf P. Steinbach /Usenet wrote:
>
> > With MSVC 10.0

>
> > std::bitset<32>( 666u )

>
> > does not compile. Apparently due to an extra constructor taking 'int'
> > argument. Is that allowed by the standard?

>
> I haven't found any wording in the Standard *prohibiting* any C++
> Standard Library implementor from supplying more functionality than
> specified in the Standard, like more c-tors, extra member functions,
> etc. *Of course, if code that would otherwise be legal becomes
> ill-formed when those new parts are added, it becomes QoI issue.
> Complain to the vendor.


IMHO clause 1.4/3 allows it:
"For classes and class templates, the library clauses specify partial
definitions.[...]"

But there is a tension with clause 1.4/8:
"A conforming implementation may have extensions, provided they do not
alter the behavior of any well-formed program.[...]"

Which mean that if a program is well formed according to the standard,
it should be well formed according to a compliant implementation
(which, I guess, is the purpose of a standard).

IMO, since std::bitset<32>( 666u ) is well formed thanks to integral
promotion, a compiler refusing it should be non-conformant.

Apart from that, it is sometimes useful like implementations of
std::string class that declare a private constructor taking a boolean
in order to avoid integral promotion of std::string(false).

--
Michael
 
Reply With Quote
 
Niels Dekker - no reply address
Guest
Posts: n/a
 
      09-03-2010
Alf P. Steinbach wrote:
> With MSVC 10.0
> std::bitset<32>( 666u )
> does not compile. Apparently due to an extra constructor taking 'int'
> argument. Is that allowed by the standard?


Victor Bazarov wrote:
> [...] Of course, if code that would otherwise be legal becomes
> ill-formed when those new parts are added, it becomes QoI issue.
> Complain to the vendor.


This issue has been reported already, by Richard Webb: "Problems
constructing a bitset from an unsigned long in the VC RC",
http://connect.microsoft.com/VisualS...details/532897

The extra contructor bitset(int) was there to fix another issue, by jkolb1,
"bitset<5> bits(0) fails with conflict between longlong and char*",
http://connect.microsoft.com/VisualS...details/500122

Which is submitted as Standard Library issue #1325, by Christopher
Jefferson: http://www.open-std.org/JTC1/sc22/WG...tive.html#1325


HTH,

Niels
--
Niels Dekker
http://www.xs4all.nl/~nd/dekkerware
Scientific programmer at LKEB, Leiden University Medical Center


 
Reply With Quote
 
Alf P. Steinbach /Usenet
Guest
Posts: n/a
 
      09-03-2010
* Niels Dekker - no reply address, on 03.09.2010 19:20:
> Alf P. Steinbach wrote:
>> With MSVC 10.0
>> std::bitset<32>( 666u )
>> does not compile. Apparently due to an extra constructor taking 'int'
>> argument. Is that allowed by the standard?

>
> Victor Bazarov wrote:
>> [...] Of course, if code that would otherwise be legal becomes
>> ill-formed when those new parts are added, it becomes QoI issue.
>> Complain to the vendor.

>
> This issue has been reported already, by Richard Webb: "Problems
> constructing a bitset from an unsigned long in the VC RC",
> http://connect.microsoft.com/VisualS...details/532897
>
> The extra contructor bitset(int) was there to fix another issue, by jkolb1,
> "bitset<5> bits(0) fails with conflict between longlong and char*",
> http://connect.microsoft.com/VisualS...details/500122
>
> Which is submitted as Standard Library issue #1325, by Christopher
> Jefferson: http://www.open-std.org/JTC1/sc22/WG...tive.html#1325


Oh my. SNAFU strikes again.

From the proposed resolution,

<code>
template <class charT>
explicit
bitset(const charT *str,
typename basic_string<charT>::size_type pos = 0,
typename basic_string<charT>::size_type n =
basic_string<charT>::npos,
charT zero = charT('0'), charT one = charT('1'));
</code>

Here charT('0') is not formally guaranteed to represent L'0' when charT is wchar_t.

Of course it works for Unicode, when the original character set isn't EBCDIC.

Oh holy Odin! And Tor! That ungood cast is actually in the C++0x draft!

If only the committee made a habit of consulting me every time they got an urge
to introduce fancy over-engineered "solutions". But no. Never heard from them.

Anyways, if anyone of them should happen to listen in, the Correct(TM) thing to
do is to /ditch/ that over-engineering -- a hammer does not need to also be a
radio receiver and refrigerator, d'u hear? -- and is otherwise exemplified by


<code>
#include <locale>
#include <iostream>

template< class CharT >
int foo( CharT c = std::use_facet< std::ctype< char > >( std::locale::classic()
).widen( '0' ) )
{
return c;
}

int main()
{
std::cout << foo<wchar_t>() << std::endl;
}
</code>


<deadpan>This clear and concise code is why I love the standard lib's
localization handling.</deadpan>

But oops, this does not compile with MSVC 10.0...


Cheers,

- Alf

--
blog at <url: http://alfps.wordpress.com>
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      09-03-2010
Niels Dekker - no reply address <(E-Mail Removed)> wrote:
> The extra contructor bitset(int) was there to fix another issue, by jkolb1,
> "bitset<5> bits(0) fails with conflict between longlong and char*",


One could argue that giving 0 as parameter to the std::bitset
constructor makes little sense. As a char* it would be invalid and
cause UB, and as an unsigned long it would be the same as not giving
anything at all (because the default constructor initializes all the
bits to zero already).

I can't think of a rational situation where one would end up giving
the *literal* 0 to the bitset constructor (giving it a an integral
variable, possibly a const, wouldn't cause a problem because its type
is unambiguous).

Maybe if one #defines the initial value of the bitset as a preprocessor
macro... Still feels a bit contrived, though.
 
Reply With Quote
 
Niels Dekker - no reply address
Guest
Posts: n/a
 
      09-03-2010
>> The extra contructor bitset(int) was there to fix another issue, by
>> jkolb1, "bitset<5> bits(0) fails with conflict between longlong and
>> char*",


Juha Nieminen wrote:
> One could argue that giving 0 as parameter to the std::bitset
> constructor makes little sense. As a char* it would be invalid and
> cause UB, and as an unsigned long it would be the same as not giving
> anything at all (because the default constructor initializes all the
> bits to zero already).
>
> I can't think of a rational situation where one would end up giving
> the *literal* 0 to the bitset constructor (giving it a an integral
> variable, possibly a const, wouldn't cause a problem because its type
> is unambiguous).


What do you mean by "possibly a const"? The following is still
ambiguous, according to the current Working Draft (N3126):

const int zeroConst = 0;
// bitset(unsigned long long) or bitset(const char*)?
std::bitset<5> bits(zeroConst);

> Maybe if one #defines the initial value of the bitset as a
> preprocessor macro... Still feels a bit contrived, though.


I have to admit I originally didn't take this use case very serious,
passing a zero-valued constant expression as constructor argument to
std::bitset. But then I realized again, that backward compatibility is
*very* important to C++. And the use case is entirely legal in C++03.
Compilers don't even warn you against it!

So I think LWG issue #1325 ("bitset") needs to be fixed.


Kind regards, Niels
--
Niels Dekker
http://www.xs4all.nl/~nd/dekkerware
Scientific programmer at LKEB, Leiden University Medical Center


 
Reply With Quote
 
Pavel
Guest
Posts: n/a
 
      09-04-2010
Juha Nieminen wrote:
> Niels Dekker - no reply address<(E-Mail Removed)> wrote:
>> The extra contructor bitset(int) was there to fix another issue, by jkolb1,
>> "bitset<5> bits(0) fails with conflict between longlong and char*",

>
> One could argue that giving 0 as parameter to the std::bitset
> constructor makes little sense. As a char* it would be invalid and
> cause UB, and as an unsigned long it would be the same as not giving
> anything at all (because the default constructor initializes all the
> bits to zero already).
>
> I can't think of a rational situation where one would end up giving
> the *literal* 0 to the bitset constructor

To initialize a static member of a class template specialization?

For a bitset, you could do = std::bitset(), of course but (0) is shorter.

-Pavel


> (giving it a an integral
> variable, possibly a const, wouldn't cause a problem because its type
> is unambiguous).
>
> Maybe if one #defines the initial value of the bitset as a preprocessor
> macro... Still feels a bit contrived, though.


 
Reply With Quote
 
joe
Guest
Posts: n/a
 
      09-05-2010
Alf P. Steinbach /Usenet wrote:>

"Are additional constructors for standard containers allowed?"

I hope not.


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Are sequence containers not a subset of general containers? Sebastian Mach C++ 5 10-06-2012 07:54 PM
Containers of iterators vs. containers of references clark.coleman@att.net C++ 7 01-25-2008 01:37 PM
Copy constructors, de/constructors and reference counts Jeremy Smith C++ 2 08-02-2006 11:25 PM
How do the STL containers interact with destructors/constructors? velthuijsen C++ 3 02-13-2004 02:52 PM
Constructors that call other Constructors Dave Rudolf C++ 12 02-06-2004 03:26 PM



Advertisments