Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #5354 > unrolled thread
| Started by | Nikos Chantziaras <realnc@arcor.de> |
|---|---|
| First post | 2011-05-23 12:07 +0300 |
| Last post | 2011-05-25 02:37 +0200 |
| Articles | 7 — 4 participants |
Back to article view | Back to comp.lang.c++
Rationale behind user provided ctor requirement for const objects of non-POD class types Nikos Chantziaras <realnc@arcor.de> - 2011-05-23 12:07 +0300
Re: Rationale behind user provided ctor requirement for const objects of non-POD class types "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-05-23 12:11 +0200
Re: Rationale behind user provided ctor requirement for const objects of non-POD class types Nikos Chantziaras <realnc@arcor.de> - 2011-05-23 13:32 +0300
Re: Rationale behind user provided ctor requirement for const objects of non-POD class types "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-05-23 13:36 +0200
Re: Rationale behind user provided ctor requirement for const objects of non-POD class types "Balog Pal" <pasa@lib.hu> - 2011-05-23 14:44 +0200
Re: Rationale behind user provided ctor requirement for const objects of non-POD class types Öö Tiib <ootiib@hot.ee> - 2011-05-24 16:04 -0700
Re: Rationale behind user provided ctor requirement for const objects of non-POD class types "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-05-25 02:37 +0200
| From | Nikos Chantziaras <realnc@arcor.de> |
|---|---|
| Date | 2011-05-23 12:07 +0300 |
| Subject | Rationale behind user provided ctor requirement for const objects of non-POD class types |
| Message-ID | <ird841$112$1@news.grnet.gr> |
(Originally posted to comp.std.c++, but that newsgroup is dead.)
Recently, I've seen a compiler (clang) that will not compile code like this:
struct A {
A() {}
};
class B {
A a_;
};
int foo()
{
const B b;
return 0;
}
It will not compile it because 'b' is const B, which does not have a
user defined ctor. C++'03 [dcl.init] p9 says:
If no initializer is specified for an object, and the object
is of (possibly cv-qualified) non-POD class type (or array
thereof), the object shall be default-initialized; if the
object is of const-qualified type, the underlying class type
shall have a user-declared default constructor.
Why is that? Why can't a const B constructed the same way as a
non-const B, using the implicitly defined default constructor?
[toc] | [next] | [standalone]
| From | "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| Date | 2011-05-23 12:11 +0200 |
| Message-ID | <irdbge$8da$1@dont-email.me> |
| In reply to | #5354 |
* Nikos Chantziaras, on 23.05.2011 11:07:
> (Originally posted to comp.std.c++, but that newsgroup is dead.)
>
> Recently, I've seen a compiler (clang) that will not compile code like this:
>
> struct A {
> A() {}
> };
>
> class B {
> A a_;
> };
>
> int foo()
> {
> const B b;
> return 0;
> }
>
> It will not compile it because 'b' is const B, which does not have a user
> defined ctor. C++'03 [dcl.init] p9 says:
>
> If no initializer is specified for an object, and the object
> is of (possibly cv-qualified) non-POD class type (or array
> thereof), the object shall be default-initialized; if the
> object is of const-qualified type, the underlying class type
> shall have a user-declared default constructor.
>
> Why is that? Why can't a const B constructed the same way as a non-const B,
> using the implicitly defined default constructor?
Bjarne Stroustrup's "The Design & Evolution of C++" is a good source of answers
to such questions.
Unfortunately I don't have it.
But often these rationales are nothing but common sense. So I guess if you check
out D&E, and if it gives a rationale, it will be that
this unchanging "value" shall have been explicitly defined by the source code,
because generally it makes no sense to /name a value/ and not define that value
explicitly.
There are times where it might makes sense (if had been allowed) to write e.g.
int const someIntValue;
but from the compiler's point of view this seems like the programmer had
forgotten to supplyh the value to be named, and anyway in such cases it's no big
hardship to explicitly state what that value is,
int const someIntValue = int();
And likewise in your example.
Cheers & hth.,
- Alf
--
blog at <url: http://alfps.wordpress.com>
[toc] | [prev] | [next] | [standalone]
| From | Nikos Chantziaras <realnc@arcor.de> |
|---|---|
| Date | 2011-05-23 13:32 +0300 |
| Message-ID | <irdd3g$co2$1@news.grnet.gr> |
| In reply to | #5356 |
On 05/23/2011 01:11 PM, Alf P. Steinbach /Usenet wrote:
> * Nikos Chantziaras, on 23.05.2011 11:07:
>> [...]
>> C++'03 [dcl.init] p9 says:
>>
>> If no initializer is specified for an object, and the object
>> is of (possibly cv-qualified) non-POD class type (or array
>> thereof), the object shall be default-initialized; if the
>> object is of const-qualified type, the underlying class type
>> shall have a user-declared default constructor.
>>
>> Why is that? Why can't a const B constructed the same way as a
>> non-const B,
>> using the implicitly defined default constructor?
>[...]
> But often these rationales are nothing but common sense. So I guess if
> you check out D&E, and if it gives a rationale, it will be that
> this unchanging "value" shall have been explicitly defined by the source
> code, because generally it makes no sense to /name a value/ and not
> define that value explicitly.
>
> There are times where it might makes sense (if had been allowed) to
> write e.g.
>
> int const someIntValue;
>
> but from the compiler's point of view this seems like the programmer had
> forgotten to supplyh the value to be named, and anyway in such cases
> it's no big hardship to explicitly state what that value is,
>
> int const someIntValue = int();
>
> And likewise in your example.
Good thinking, but it doesn't seem to apply. Consider this:
#include <iostream>
class A {
int x_;
public:
A() : x_(5) { }
int x() const { return x_; }
};
class B: public A { };
int main()
{
const B b;
std::cout << b.x() << "\n";
}
With compilers that accept this, the output of the program is "5". But
the C++ standard says that it should not be compilable. In this case
however, 'b' has a perfectly fine initial state.
Also, let's not forget that an object can have mutable members, so the
requirement for a user defined ctor for const B makes even less sense.
[toc] | [prev] | [next] | [standalone]
| From | "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| Date | 2011-05-23 13:36 +0200 |
| Message-ID | <irdgff$5n0$1@dont-email.me> |
| In reply to | #5357 |
* Nikos Chantziaras, on 23.05.2011 12:32:
> On 05/23/2011 01:11 PM, Alf P. Steinbach /Usenet wrote:
>> * Nikos Chantziaras, on 23.05.2011 11:07:
>>> [...]
>>> C++'03 [dcl.init] p9 says:
>>>
>>> If no initializer is specified for an object, and the object
>>> is of (possibly cv-qualified) non-POD class type (or array
>>> thereof), the object shall be default-initialized; if the
>>> object is of const-qualified type, the underlying class type
>>> shall have a user-declared default constructor.
>>>
>>> Why is that? Why can't a const B constructed the same way as a
>>> non-const B,
>>> using the implicitly defined default constructor?
>> [...]
>> But often these rationales are nothing but common sense. So I guess if
>> you check out D&E, and if it gives a rationale, it will be that
>> this unchanging "value" shall have been explicitly defined by the source
>> code, because generally it makes no sense to /name a value/ and not
>> define that value explicitly.
>>
>> There are times where it might makes sense (if had been allowed) to
>> write e.g.
>>
>> int const someIntValue;
>>
>> but from the compiler's point of view this seems like the programmer had
>> forgotten to supplyh the value to be named, and anyway in such cases
>> it's no big hardship to explicitly state what that value is,
>>
>> int const someIntValue = int();
>>
>> And likewise in your example.
>
> Good thinking, but it doesn't seem to apply. Consider this:
>
> #include <iostream>
>
> class A {
> int x_;
> public:
> A() : x_(5) { }
> int x() const { return x_; }
> };
>
> class B: public A { };
>
> int main()
> {
> const B b;
> std::cout << b.x() << "\n";
> }
I think this is completely like the `someIntValue` case. You want any value of
class `B`, or perhaps the default value. Then for this special case it's no big
deal to write
B const b = B();
just as with the `someIntValue`.
> With compilers that accept this, the output of the program is "5". But the C++
> standard says that it should not be compilable. In this case however, 'b' has a
> perfectly fine initial state.
>
> Also, let's not forget that an object can have mutable members, so the
> requirement for a user defined ctor for const B makes even less sense.
As I see it mutable members are pretty irrelevant, because their mutability
should not affect the externally visible state. E.g., a mutable member might be
used for caching for some costly-to-compute result, for example a matrix
determinant, but the using code does not see any state change. Thus, declaring a
`const` object of such a well-designed class is no different; it is conceptually
to name an unchanging value, which "should" be specified.
Cheers & hth.,
- Alf
--
blog at <url: http://alfps.wordpress.com>
[toc] | [prev] | [next] | [standalone]
| From | "Balog Pal" <pasa@lib.hu> |
|---|---|
| Date | 2011-05-23 14:44 +0200 |
| Message-ID | <irdkr1$2cng$1@news.ett.com.ua> |
| In reply to | #5358 |
"Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com>
> I think this is completely like the `someIntValue` case. You want any
> value of class `B`, or perhaps the default value. Then for this special
> case it's no big deal to write
>
> B const b = B();
Provided B is copyable :-((. The "can e declaration" bullshit takes its
usual toll. Normally you'd say
B const b();
but that is interpreted as a function.
At least we know the rationalte for that one: inherited from C without
change. Just like for() scoping this should be revised too.
I tried the b{} form with the code example upstream in current Cameau, no
luck. Not sure whether it is the mandated behavior or just the brace init is
not yet implemented.
[toc] | [prev] | [next] | [standalone]
| From | Öö Tiib <ootiib@hot.ee> |
|---|---|
| Date | 2011-05-24 16:04 -0700 |
| Message-ID | <cbd27800-24ca-4e5a-9e7e-34369de6569e@w10g2000yqa.googlegroups.com> |
| In reply to | #5361 |
On May 23, 3:44 pm, "Balog Pal" <p...@lib.hu> wrote: > "Alf P. Steinbach /Usenet" <alf.p.steinbach+use...@gmail.com> > > > I think this is completely like the `someIntValue` case. You want any > > value of class `B`, or perhaps the default value. Then for this special > > case it's no big deal to write > > > B const b = B(); > > Provided B is copyable :-((. The "can e declaration" bullshit takes its > usual toll. Normally you'd say > > B const b(); > > but that is interpreted as a function. So you need non-copyable, immutable and default-constructed instance. If such need is common then the class may be made to provide reference to one with a static member function. I sometimes do it for "null" objects. B const& b = B::none(); If you really need separate instance (why?) then aren't there some syntax that will be not interpreted as function like 'B const b(());' or something?
[toc] | [prev] | [next] | [standalone]
| From | "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| Date | 2011-05-25 02:37 +0200 |
| Message-ID | <irhii8$hul$1@dont-email.me> |
| In reply to | #5462 |
* Öö Tiib, on 25.05.2011 01:04: > On May 23, 3:44 pm, "Balog Pal"<p...@lib.hu> wrote: >> "Alf P. Steinbach /Usenet"<alf.p.steinbach+use...@gmail.com> >> >>> I think this is completely like the `someIntValue` case. You want any >>> value of class `B`, or perhaps the default value. Then for this special >>> case it's no big deal to write >> >>> B const b = B(); >> >> Provided B is copyable :-((. The "can e declaration" bullshit takes its >> usual toll. Normally you'd say >> >> B const b(); >> >> but that is interpreted as a function. > > So you need non-copyable, immutable and default-constructed instance. > > If such need is common then the class may be made to provide reference > to one with a static member function. I sometimes do it for "null" > objects. > > B const& b = B::none(); > > If you really need separate instance (why?) then aren't there some > syntax that will be not interpreted as function like 'B const b(());' > or something? I think that with C++03 rules B const& b = B(); should do it, while with C++98 this would (as I recall) require a copy constructor to be accessible. But I don't have time to check out the standard, sorry. Cheers, - Alf -- blog at <url: http://alfps.wordpress.com>
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web