- Quick simple question: - 9 Updates
- Confusing passage in C++ book - 3 Updates
- Zeroing in the constructor - 2 Updates
- A confusing topic in Stroustrup's book - 6 Updates
- Quick simple question: - 2 Updates
- Could you explain this struct BaseConstructor to me? - 2 Updates
- How to get signed zeros in C++/C? - 1 Update
ram@zedat.fu-berlin.de (Stefan Ram): Jun 12 05:16PM >I do not understand the »not«. The value of »,« >is its right operand. So »(1, S::x)« is effectively >»S::x«. Why does it say that »S::x« is /not/ odr-used? Ok. In the meantime, I learned that odr-usage has to do with S::x being used as an lvalue, not just as an rvalue. In the line with the comma »,«, only the /rvalue/ of S::x is used. But f(S::x) has an lvalue- reference parameter. |
ram@zedat.fu-berlin.de (Stefan Ram): Jun 12 06:14PM Executive Summary: Where does the C++ standard describe the effects of brace-or-equal-initializers of member-declarators of non-static data members of primitive type? I have a problem finding wording in the standard that says that the following program will print »25«. #include <iostream> #include <ostream> struct entity { double value = 25; }; int main(){ entity e; ::std::cout << e.value << '\n'; } I am searching near 9.2 Class members [class.mem] . There, I find: member-declarator: declarator brace-or-equal-initializer opt and also 4 A brace-or-equal-initializer shall appear only in the declaration of a data member. . But what I'd like to read is something like this wording: »The brace-or-equal-initializer is used to initialized the data member when a new instance of the class is being created.« In some cases »8.5.1 Aggregates« might be appropriate, but not all classes with brace-or-equal-initializer in member declarations are aggregates. 12.1 says: »The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer (12.6.2) and an empty compound-statement.« -- so we also cannot say that its the implicitly-defined default constructor that will execute the brace-or-equal-initializers of member-declarators. So, where does the C++ standard describe the effects of brace-or-equal-initializers of member-declarators of non-static data members of primitive type? |
ram@zedat.fu-berlin.de (Stefan Ram): Jun 12 06:32PM >performs the set of initializations of the class that would >be performed by a user-written default constructor for that >class with no ctor-initializer (12.6.2) and an empty 12.6.2p10 also says: »If a given non-static data member has both a brace-or-equal-initializer and a mem-initializer, the initialization specified by the mem-initializer is performed, and the non-static data member's brace-or-equal-initializer is ignored.« This also is close. It does suggest, but does not explicitly say that the non-static data member's brace-or-equal-initialize /is used/ to initializie the non-static data member in the case that a non-static data member does /not/ have a mem-initializer. |
ram@zedat.fu-berlin.de (Stefan Ram): Jun 12 06:38PM >brace-or-equal-initialize /is used/ to initializie the >non-static data member in the case that a non-static data >member does /not/ have a mem-initializer. Is it possible that in the case of struct entity { double value = 25; }; the following wording 12.6.2p9 applies? 9 In a non-delegating constructor, if a given potentially constructed subobject is not designated by a meminitializer-id (including the case where there is no mem-initializer-list because the constructor has no ctorinitializer), then (9.1) --- if the entity is a non-static data member that has a brace-or-equal-initializer and either (9.1.1) --- the constructor's class is a union (9.5), and no other variant member of that union is designated by a mem-initializer-id or (9.1.2) --- the constructor's class is not a union, and, if the entity is a member of an anonymous union, no other member of that union is designated by a mem-initializer-id, the entity is initialized as specified in 8.5; |
ram@zedat.fu-berlin.de (Stefan Ram): Jun 12 06:50PM Richard writes: >The 3rd argument in the snippet above is simply an unnamed argument of >type "forward_iterator_tag". As mentioned in other responses, the >standard library defines some types for the various iterators: This shows that it sometimes might improve readability to write #include <iterator> // struct ::std::forward_iterator_tag ... void sort_helper(For beg, For end, struct ::std::forward_iterator_tag ) , because the reader now can immediately see that this is a type name and it comes from the standard library. I don't know whether the following also is legal. void sort_helper(For beg, For end, typename ::std::forward_iterator_tag ) , but if so, it might be more appropriate so as to make clear that it is a type while hiding the actual implementation of the tag type as a class. |
ram@zedat.fu-berlin.de (Stefan Ram): Jun 12 09:08PM >Iterator_type<C> is a system template, >but I can't find a description of it When the type I is ::std::move_iterator< T > or ::std::reverse_iterator< T >, then I::iterator_type is T. So, we can define: #include <iostream> #include <ostream> #include <array> #include <iterator> template< typename C > using Iterator_type = typename C::iterator_type; int main() { ::std::array< int, 2 >a={ 17, 2 }; auto iterator = ::std::begin( a ); using iterator_type = decltype( iterator ); ::std::move_iterator< iterator_type >::iterator_type i0 = iterator; ::std::reverse_iterator< iterator_type >::iterator_type i1 = iterator; Iterator_type< ::std::move_iterator< iterator_type >> i2 = iterator; Iterator_type< ::std::reverse_iterator< iterator_type >>i3 = iterator; ::std::cout << *i0 << '\n'; ::std::cout << *i1 << '\n'; ::std::cout << *i2 << '\n'; ::std::cout << *i3 << '\n'; } 17 17 17 17 |
ram@zedat.fu-berlin.de (Stefan Ram): Jun 12 09:19PM >Confusing passage in C++ book When you write a subject line for a post, you should use a subject that describes the technical topic of your question. For example, here a good subject would be: »the value of the assignment operator«. Don't use uninformative broad subjects, such as »I read this in a book«, »I have a C++ question«, »A question about the C++ language«, or »Here's another question from me«. |
ram@zedat.fu-berlin.de (Stefan Ram): Jun 12 09:40PM >>subject that describes the technical topic of your question. >Yeah! You tell him, Stefan! It ought to be a subject like like "Quick >simple question:" or "typename" or "some experiments with type names" Today is the subject-line awareness day. To raise the awareness of the importance of technically specific subject lines, I indeed have posted some posts with an intentionally uninformative subject line »Quick simple question:«. Possibly, I will not continue this beyond this subject-line awareness day. |
ram@zedat.fu-berlin.de (Stefan Ram): Jun 12 09:53PM >an intentionally uninformative subject line »Quick simple >question:«. Possibly, I will not continue this beyond this >subject-line awareness day. To explain this better, I would like to remind the newsgroup that on April 20, 2015, I already posted this: |Newsgroups: comp.lang.c++ |Subject: Re: Quick Question |From: ram@zedat.fu-berlin.de (Stefan Ram) | |Doug Mika <dougmmika@gmail.com> writes: |>Subject: Quick Question | | You should use more specific subject lines in Usenet. | But the person addressed was not willing to consider this suggestion on subsequent posts. Instead we still get more and more subjects lines, like, recently: »Quick simple question:«. |
Paul <pepstein5@gmail.com>: Jun 12 02:13PM -0700 The passage quoted below seems to say that a=b=c; is only allowed if assignment returns a reference. This doesn't seem correct (to me). Assignment is right-associative. Even if operator = was written to return by value, it seems (to me) that a = b = c; would be fine. So I don't get why he says that you need to return a reference to allow chained assignments. I do agree that you need to return a non-const reference to be able to write (a = b) = c; Thanks for your help, Paul BEGIN QUOTE For IntCell, the signatures of these operations are ~IntCell( ); // Destructor IntCell( const IntCell & rhs ); // Copy constructor IntCell( IntCell && rhs ); // Move constructor IntCell & operator= ( const IntCell & rhs ); // Copy assignment IntCell & operator= ( IntCell && rhs ); // Move assignment The return type of operator= is a reference to the invoking object, so as to allow chained assignments a=b=c. Though it would seem that the return type should be a const reference, so as to disallow nonsense such as (a=b)=c, that expression is in fact allowed in C++ even for integer types. Hence, the reference return type (rather than the const reference return type) is customarily used but is not strictly required by the language specification. END QUOTE |
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 12 05:29PM -0400 On 6/12/2015 5:13 PM, Paul wrote: > IntCell & operator= ( IntCell && rhs ); // Move assignment > The return type of operator= is a reference to the invoking object, > so as to allow chained assignments a=b=c. Though it would seem that the return type should be a const reference, so as to disallow nonsense such as (a=b)=c, that expression is in fact allowed in C++ even for integer types. Hence, the reference return type (rather than the const reference return type) is customarily used but is not strictly required by the language specification. > END QUOTE You're correct. The non-const reference return was actually to allow calling a member function on the result of assignment, I think, something like (b = c).foo(); The idea was that such code should be equivalent to b = c; b.foo(); And, if 'b' was possible to assign to, then it should be possible to call a non-const member function in the same scope, hence it should be possible to combine those in a single expression. If the assignment returned some other type, calling a non-const member would be problematic, I think. V -- I do not respond to top-posted replies, please don't ask |
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 12 05:34PM -0400 On 6/12/2015 5:19 PM, Stefan Ram wrote: >> Confusing passage in C++ book > When you write a subject line for a post, you should use a > subject that describes the technical topic of your question. Yeah! You tell him, Stefan! It ought to be a subject like like "Quick simple question:" or "typename" or "some experiments with type names" There is a Russian saying "Чья бы корова мычала..."; I think Americans use the expression "You're a fine one to talk!". Look it up! > »I have a C++ question«, > »A question about the C++ language«, or > »Here's another question from me«. V -- I do not respond to top-posted replies, please don't ask |
Noob <root@127.0.0.1>: Jun 12 10:54PM +0200 Hello, I've taken a look at a medium-sized C++ legacy code-base which crashes in several places. (NB: I'm a C coder.) Turns out the program defines several large classes (~50 fields, mostly int's or int arrays, and a few pointers). The constructor is supposed to set everything to 0s and NULLs, but it misses a few fields, and the program blows up when it uses one of these uninitialized fields. I was thinking: instead of trying to figure out which fields are missing in the constructor, I could just bulldoze the entire object: std::memset(this, 0, sizeof *this); (The code doesn't use the virtual keyword anywhere.) Will this work as expected? Regards. |
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 12 05:20PM -0400 On 6/12/2015 4:54 PM, Noob wrote: > std::memset(this, 0, sizeof *this); > (The code doesn't use the virtual keyword anywhere.) > Will this work as expected? You could, and we used to do that. However such practice is frowned upon. So, don't tell anybody and put lots of warnings in the header not to add any virtual functions or else! However, in terms of software engineering, I believe it would actually be better to add the missing initializers and also add verification (of the same sort, like memcmp or whatever is available) and throw an exception if the verification does not pass. V -- I do not respond to top-posted replies, please don't ask |
Doug Mika <dougmmika@gmail.com>: Jun 12 10:21AM -0700 On Friday, June 12, 2015 at 11:39:46 AM UTC-5, Victor Bazarov wrote: > V > -- > I do not respond to top-posted replies, please don't ask Let's stick with one question at a time: what is "Iterator_type<C>"? Is it a reserved word like "decltype"? (No I think or I would have found it). Is it a template class? If so, what library is it in (www.cplusplus.com finds no such keyword Iterator_type) |
Paavo Helde <myfirstname@osa.pri.ee>: Jun 12 12:39PM -0500 Doug Mika <dougmmika@gmail.com> wrote in > (No I think or I would have found it). Is it a template class? If > so, what library is it in (www.cplusplus.com finds no such keyword > Iterator_type) It looks like a template class indeed. I understand this is an example from a book. Most probably the book assumes this is defined earlier in the code. Probably the book contains the definition of Iterator_type somewhere. Have you looked in the book index? Anyway, it looks like a helper class which is used for deducing the needed iterator type from the container type, maybe even for such containers as C- style arrays. hth Paavo |
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 12 01:51PM -0400 On 6/12/2015 1:21 PM, Doug Mika wrote: > Is it a reserved word like "decltype"? (No I think or I would have > found it). Is it a template class? If so, what library is it in > (www.cplusplus.com finds no such keyword Iterator_type) It is not "a template class". There is no such thing as "a template class". It is, in fact, a *class template*. It is not a reserved word. It is a template that is defined somewhere. From what you have posted I can only determine that it has at least one argument, that its argument is a type, and I can conclude that it probably a special constuct/template to be used in combination with other templates, like the 'Iterator_category'. Those are specialized for known containers somehow. You need to look for more code (possibly in other sections/chapters) to see how they are defined. The Standard Library has similar templates/types defined: namespace std { struct input_iterator_tag { }; struct output_iterator_tag { }; struct forward_iterator_tag: public input_iterator_tag { }; struct bidirectional_iterator_tag: public forward_iterator_tag { }; struct random_access_iterator_tag : public bidirectional_iterator_tag { }; } For 'std::vector' its 'iterator' type is implementation-defined, but it is such that its traits defined its category as 'random access', probably. It's a bit more involved than the simplistic examples in the book, but it's not impossible to follow all the definitions and unravel them to see the relationships and how they are instantiated. V -- I do not respond to top-posted replies, please don't ask |
legalize+jeeves@mail.xmission.com (Richard): Jun 12 06:41PM [Please do not mail me a copy of your followup] Doug Mika <dougmmika@gmail.com> spake the secret code >QUESTION: I have never seen the paramters of a function be in the format >"forward_iterator_tag", I have always only seen "Type instance" ie "int >myInt". What is "forward_iterator_tag", and where is its type? The 3rd argument in the snippet above is simply an unnamed argument of type "forward_iterator_tag". As mentioned in other responses, the standard library defines some types for the various iterators: <http://en.cppreference.com/w/cpp/iterator/iterator_tags> These types are called "tags" because they only exist to allow you to select implementations of an algorithm based on the type of the tag. In this case, the right implementation of the template function sort_helper() is being selected for forward iterators through function overloading. > using Iter = Iterator_type<C>; > sort_helper(c.begin(),c.end(),Iterator_category<Iter>{}); >} Here he is using his own "Iterator_category<Iter>{}" helper as a "meta function" -- a thing that takes a type (in this case, the type of the iterator Iter) and returns another type (in this case, the associated iterator category type). >1)How would this sort template look if we were to not have using Iter = >Iterator_type<C>;? What does this line do? - I have never seen it used >in this context. Iterator_type<C> is also an invocation of his own little template meta function. I don't have my 4th edition handy here, but I remember that he is pretty good about making sure he describes these in the text before using them. >2)What is Iterator_type and Iterator_category? I searched for these on >www.cplusplus.com but found nothing that would make it clear. They are Bjarne's helpers that simplify things slightly by eliminating a little syntax. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Doug Mika <dougmmika@gmail.com>: Jun 12 01:54PM -0700 On Friday, June 12, 2015 at 12:39:37 PM UTC-5, Paavo Helde wrote: > style arrays. > hth > Paavo Iterator_type<C> is a system template, but I can't find a description of it anywhere... (The book doesn't define it). Arrrgghhh it's frustrating, it's a neat example making this even more upsetting. |
Doug Mika <dougmmika@gmail.com>: Jun 12 02:05PM -0700 On Friday, June 12, 2015 at 3:54:18 PM UTC-5, Doug Mika wrote: > > hth > > Paavo > Iterator_type<C> is a system template, but I can't find a description of it anywhere... (The book doesn't define it). Arrrgghhh it's frustrating, it's a neat example making this even more upsetting. Come to think of it, it may be one of his own constructs, but it certainly isn't in the book - at least Adobe's find didn't locate it in my digital copy of the book....argghhh |
Luca Risolia <luca.risolia@linux-projects.org>: Jun 12 07:34PM +0200 Il 12/06/2015 18:27, K.Frank ha scritto: > double res1; > double res2; > thread t1 {f,some_vec,&res1}; //f(some_vec,&res1) executes in a separate Sorry, typo: it's clear what I meant to say "res" is *a copy* of the passed pointer which is "&res1" - not "res1", of course. I read your "you don't want to access res1" as if one could not write res1 (which is a pointer itself), which is clearly perfectly safe. You probably meant to say "dereference" instead of "access". However, I think what is important for the OP to notice in his example is that what you get in f(), when it is invoked in the context of a new thread of execution, is a const reference to **A COPY** of the original vector passed as argument to the thread constructor. ** A COPY ** allocated in a thread-specific storage, as if by the function: template <class T> typename decay<T>::type decay_copy(T&& v) { return std::forward<T>(v); } Many people actually fail to understand that. For this reason, most of the times what you really need is to wrap the things with std::cref() or std::ref() to share the same data between threads. |
Luca Risolia <luca.risolia@linux-projects.org>: Jun 12 08:04PM +0200 Il 12/06/2015 17:34, Doug Mika ha scritto: > Args> explicit thread (Fn&& fn, Args&&... args);, > don't the && imply > "moving" of the arguments as they are/expect rvalues?) No. Due to reference collapsing rules, an Arg&& becomes Arg& if you pass an lvalue ref as argument (Arg&& & -> Arg&). To answer your question then, you can "choose" by explicit casting your arguments to lvalue-references or rvalue-references respectively. |
fl <rxjwg98@gmail.com>: Jun 12 10:13AM -0700 On Friday, June 12, 2015 at 9:45:13 AM UTC-7, Victor Bazarov wrote: > V > -- > I do not respond to top-posted replies, please don't ask Thanks for your reply. Here is other code. In fact, I have a further question when I read it. 'class Complex' is derived from Number. In the same time, class Number is its friend class. I see this kind of thing the first time. A child class needs its parent (base) class to operate on it? Thanks, .............. class Complex : public Number { friend class RealNumber; friend class Number; Complex (double d, double e); Complex (const Complex &c); virtual ~Complex (); virtual Number operator + (Number const &n) const; virtual Number realAdd (Number const &n) const; virtual Number complexAdd (Number const &n) const; double rpart, ipart; }; class RealNumber : public Number { friend class Complex; friend class Number; RealNumber (double r); RealNumber (const RealNumber &r); virtual ~RealNumber (); virtual Number operator + (Number const &n) const; virtual Number realAdd (Number const &n) const; virtual Number complexAdd (Number const &n) const; double val; }; /// Used only by the letters. Number::Number (BaseConstructor): rep (0), referenceCount (1) {} /// Used by user and static factory functions. Number::Number () : rep (0), referenceCount (0) {} /// Used by user and static factory functions. Number::Number (const Number &n): rep (n.rep), referenceCount (0) { cout << "Constructing a Number using Number::Number\n"; if (n.rep) n.rep->referenceCount++; } Number Number::makeReal (double r) { Number n; n.redefine (new RealNumber (r)); return n; } Number Number::makeComplex (double rpart, double ipart) { Number n; n.redefine (new Complex (rpart, ipart)); return n; } Number::~Number() { if (rep && --rep->referenceCount == 0) delete rep; } Number & Number::operator = (const Number &n) { cout << "Assigning a Number using Number::operator=\n"; Number temp (n); this->swap (temp); return *this; } |
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 12 01:34PM -0400 On 6/12/2015 1:13 PM, fl wrote: > Thanks for your reply. Here is other code. > In fact, I have a further question when I read it. 'class Complex' is > derived from Number. In the same time, class Number is its friend class. In order to convince yourself about the necessity of doing that (making the derived a friend of the base and vice versa), try commenting out the 'friend' declaration and see what errors about access you get when compiling. > I see this kind of thing the first time. A child class needs its parent > (base) class to operate on it? The derived classes have no public members. All members are therefore private. In order to even construct an object of that type you need to either be a member or be a friend. > { > Number n; > n.redefine (new RealNumber (r)); In order to compile this particular line, 'Number' has to be a friend of 'RealNumber'. > { > Number n; > n.redefine (new Complex (rpart, ipart)); In order to compile this particular line, 'Number' has to be a friend of 'Complex'. > this->swap (temp); > return *this; > } I am still unsure about the 'BaseConstructor' role, but I think it's to prevent some unpleasantness, but which unpleasantness, is still foggy to me and I'm too lazy to take your code and compile it while playing with c-tors and access specifiers; you can do it. Try redefining Number(BaseConstructor) to be explicit Number(int). V -- I do not respond to top-posted replies, please don't ask |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jun 12 12:55AM +0100 On 11/06/2015 21:43, Paavo Helde wrote: > inf > See there. It is inf, regardless or whether you or me like it or not (I > do!) If you write code that treats division by zero as infinity then you better keep that code to yourself; the world doesn't need it. /Flibble |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment