- User-defined access operator? - 2 Updates
- Random Device initialization is platform dependant? - 5 Updates
- X operator=(const &X) - 15 Updates
- implementation of daemon thread - 2 Updates
Marcel Mueller <news.5.maazl@spamgourmet.org>: Dec 09 09:32PM +0100 On 08.12.16 23.53, bitrex wrote: > Am I correct in understanding that there's no way to treat this > pool-allocated wrapper type as if it were a "regular" object > instantiated on the stack? Exactly. You cannot override the "operator.". > obj.x = 7; //not okay, pool_object_t<MyPODStruct> has no member named "x" > Maybe I should just make the pool_object_t more like a smart pointer, Exactly too. You can virtualize only reference types. In fact your type /is/ a reference type. Marcel |
bitrex <bitrex@de.lete.earthlink.net>: Dec 09 05:27PM -0500 On 12/09/2016 03:32 PM, Marcel Mueller wrote: > Exactly too. You can virtualize only reference types. > In fact your type /is/ a reference type. > Marcel Thanks. Reading a little more, I should probably make my pool class conform to the "custom allocator" standard for C++11, and then I could use it with STL containers. I could also write a smart pointer-like wrapper around it to return lone reference objects. |
bartekltg <bartek@gmail.com>: Dec 09 02:10AM +0100 On 07.12.2016 22:21, Richard wrote: >> object with the time. You should only seed a generator once, so you >> need to make the mt19937 object static: > Nit: static objects like this make unit testing more difficult. Do you prefer a global mt19937 object? ;> bartekltg |
bartekltg <bartek@gmail.com>: Dec 09 02:24AM +0100 On 07.12.2016 22:14, Ben Bacarisse wrote: > need to make the mt19937 object static: >> std::mt19937 gen(rd()); > static std::mt19937 gen(std::time(0)); You can meet in the middle, std::random_device rd; static std::mt19937 gen(rd() + std::time(0)); or something like: auto t = std::chrono::high_resolution_clock::now(); std::chrono::time_point<std::chrono::high_resolution_clock> now() ; static std::mt19937 gen2(rd() + t.time_since_epoch().count()); If random_device works, we have good seed, an addition would not break it ( probably... No one can be sure that his random_device do not terurn - std::time(0) ;-) and if it didn't work, seed still isn't constant. bartekltg |
Christian Steins <cs01@quantentunnel.de>: Dec 09 11:24AM +0100 Am 09.12.2016 um 02:24 schrieb bartekltg: > You can meet in the middle, > std::random_device rd; > static std::mt19937 gen(rd() + std::time(0)); Simple and good solution. Until a get_seed() or something is added to the STL. Christian |
legalize+jeeves@mail.xmission.com (Richard): Dec 09 06:28PM [Please do not mail me a copy of your followup] bartekltg <bartek@gmail.com> spake the secret code >>> need to make the mt19937 object static: >> Nit: static objects like this make unit testing more difficult. >Do you prefer a global mt19937 object? ;> Perhaps, it depends on the situation. A scoped static is essentially a global variable that you can't access from outside that scope. This means that in a unit test scenario you have no way in which you can reset this state. Therefore you can't write a repeatable test of any code that is calling the generator. The local statics are hidden global state. Global state makes unit testing difficult. The typical solution is to use dependency injection in order to allow the code to be repeatably tested. In this case, injecting the dependent state of the random number generator would solve the problem and make the code testable. So yes, a global variable that is injected by the caller would make this code more testable. You can achieve the same end-user API by making a simple delegating function that injects the global state and forwards any other arguments. This frees callers from having to know about this global state and the delegated function can still be unit tested. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Terminals Wiki <http://terminals-wiki.org> The Computer Graphics Museum <http://computergraphicsmuseum.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
legalize+jeeves@mail.xmission.com (Richard): Dec 09 07:59PM [Please do not mail me a copy of your followup] (Richard) legalize+jeeves@mail.xmission.com spake the secret code >Nit: static objects like this make unit testing more difficult. Also nit: they can lead to difficult bugs in multi-threaded code. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Terminals Wiki <http://terminals-wiki.org> The Computer Graphics Museum <http://computergraphicsmuseum.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Ralf Goertz <me@myprovider.invalid>: Dec 09 09:37AM +0100 Hi, consider the following program #include <iostream> struct X { const int & cr; int var; X(const int &cr_) : cr(cr_),var(0) {} X child() { X ret(*this); ret.var++; return ret; } //X operator=(const X& other) {X ret(*this);return ret;} //(*) }; int main() { int k=42; X x(k); x=x.child(); std::cout<<x.var<<std::endl; } It doesn't compile without the operator definition (*). The error message is childtest.cc: In function 'int main()': childtest.cc:18:6: error: use of deleted function 'X& X::operator=(X&&)' x=x.child(); ^ childtest.cc:3:8: note: 'X& X::operator=(X&&)' is implicitly deleted because the default definition would be ill-formed: struct X { ^ childtest.cc:3:8: error: non-static reference member 'const int& X::cr', can't use default assignment operator When I uncomment (*) it compiles but the program prints „0" instead of the expected „1". There are a few ways to fix this. First, I could make cr of type „int", so no reference and non-const. That would work. But in the real world X is a heavy type and I need to x=x.child() all the time in a recursive function. That would mean a waste of space and performance. Also X y=x.child() and outputting y also works correctly without (*) By the way, this was compiled using -std=c++11, but the problem is also present without it. The only difference is it complaints about X& instead of X&& in the deleted operator. What is going on and how can I fix this? Thanks |
"Öö Tiib" <ootiib@hot.ee>: Dec 09 01:26AM -0800 On Friday, 9 December 2016 10:37:36 UTC+2, Ralf Goertz wrote: > return ret; > } > //X operator=(const X& other) {X ret(*this);return ret;} //(*) Note that here is rather unusual assignment operator commented out that does not modify 'this' object at all (IOW does not assign). May be it is the source of your self-confusion? > std::cout<<x.var<<std::endl; > } > It doesn't compile without the operator definition (*). How you want compiler to generate copy or move assignment? Your class has reference member. References are immutable after declaration so can not be neither copied nor moved to already existing reference. > The error message is Basically saying exactly what what I said in lot better English and more detail than I can produce. > When I uncomment (*) it compiles but the program prints „0" instead of > the expected „1". The output "0" is what I would expect from the program posted and with (*) uncommented. Can you tell why you expect "1"? |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 09 10:32AM +0100 On 09.12.2016 09:37, Ralf Goertz wrote: > ^ > childtest.cc:3:8: error: non-static reference member 'const int& > X::cr', can't use default assignment operator And? Isn't that clear? Cheers!, - Alf |
Ralf Goertz <me@myprovider.invalid>: Dec 09 10:50AM +0100 Am Fri, 9 Dec 2016 10:32:33 +0100 > > X::cr', can't use default assignment operator > And? > Isn't that clear? It is clear, that's why I tried to define my own assignment operator, but I obviously failed. What would be the correct way to do it when I really want cr to be a constant reference? |
Ralf Goertz <me@myprovider.invalid>: Dec 09 10:52AM +0100 Am Fri, 9 Dec 2016 01:26:25 -0800 (PST) > Note that here is rather unusual assignment operator commented > out that does not modify 'this' object at all (IOW does not assign). > May be it is the source of your self-confusion? Yep that seems to be the problem. What would be the correct definition? This definition X operator=(const X& other) { cr=other.cr;var=other.var} doesn't work either. |
Paavo Helde <myfirstname@osa.pri.ee>: Dec 09 12:00PM +0200 On 9.12.2016 11:50, Ralf Goertz wrote: > It is clear, that's why I tried to define my own assignment operator, > but I obviously failed. What would be the correct way to do it when I > really want cr to be a constant reference? #include <iostream> struct X { const int & cr; int var; X(const int &cr_): cr(cr_), var(0) {} X child() { X ret(*this); ret.var++; return ret; } X& operator=(const X& other) { this->~X(); new (this) X(other); return *this; } }; int main() { int k = 42; X x(k); x = x.child(); std::cout<<x.var<<std::endl; } |
Paavo Helde <myfirstname@osa.pri.ee>: Dec 09 12:06PM +0200 On 9.12.2016 12:00, Paavo Helde wrote: > new (this) X(other); > return *this; > } Correction: X& operator=(const X& other) { if (this!=&other) { this->~X(); new (this) X(other); } return *this; } |
Ralf Goertz <me@myprovider.invalid>: Dec 09 11:09AM +0100 Am Fri, 09 Dec 2016 12:00:34 +0200 > new (this) X(other); > return *this; > } Thanks, that seems to work. Do I need to worry about memory leakage since I use new without delete? |
"Öö Tiib" <ootiib@hot.ee>: Dec 09 02:50AM -0800 On Friday, 9 December 2016 12:09:35 UTC+2, Ralf Goertz wrote: > > } > Thanks, that seems to work. Do I need to worry about memory leakage > since I use new without delete? That code contains "placement new" not usual "new". It does not allocate memory but instead uses memory that was given to it with argument. |
Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid>: Dec 09 01:58PM +0100 >> } > Thanks, that seems to work. Do I need to worry about memory leakage > since I use new without delete? There is no memory allocation here, this can't cause leakage. But you need to worry about your design: defining a struct with a const ref member *and* an assignment operator does not make much sense. Paavo's solution essentially bypasses the inherent incoherence by using destructor and constructor, but the problem remains: your design is absurd. -- Alain. |
Ralf Goertz <me@myprovider.invalid>: Dec 09 03:23PM +0100 Am Fri, 09 Dec 2016 13:58:38 +0100 > sense. Paavo's solution essentially bypasses the inherent incoherence > by using destructor and constructor, but the problem remains: your > design is absurd. Okay, I am open to suggestions as to the design, although with Paavo's solution, everything works as expected. My X is a class used in a generic backtracking algorithm I have written. It contains the status that changes when creating new chlidren or siblings. template <class Status> class Backtrack { bool findAll, isValid; Status state; bool reject(); bool accept(); Backtrack<Status> first(); Backtrack<Status> next(); void output(); public: Backtrack(Status initial, bool fa=false) : findAll(fa),state(initial),isValid(true) {} void bt() { //code according to the pseudo code in the wikipedia //article on backtracking } }; I've used that code in a number of projects now by writing appropriate functions reject(), accept(), first(), next(), and output(). It always bothered me that I couldn't have members of Status which are const &, although it might contain immutable information that is needed at all levels of the search tree. My attempt is not to expose that information if it is not necessary. Therefore, I want to avoid a global variable. Also, a static member variable feels wrong since it must be accessed from outside the class and I want to be able to have more than one variable of class Backtrack<X> with different information in state. With my design now I only need my „Special" Status class and Backtrack<Special> b; b.bt(Special(…),true); and I can use different parameters in … As I said, „Special" can be very big with only a few bits of information actually changing. Therefore, I try to only make those parts variable and keep the rest const & as in the example in the OP to avoid copying all the big stuff. Any comments? |
Paavo Helde <myfirstname@osa.pri.ee>: Dec 09 04:29PM +0200 On 9.12.2016 12:09, Ralf Goertz wrote: >> } > Thanks, that seems to work. Do I need to worry about memory leakage > since I use new without delete? No, there is no leak because there is no actual memory allocation involved. However, you need to worry about self-assignment (fixed in my followup post) and also you need to worry about exception throwing in the constructor and destructor. If they happen to throw, then the object may remain in an inconsistent/unusable state. In your simple example there is no possibility of exceptions, but in real life this is something to consider, and one might need to add some try-catch block and restore the object into some valid fallback state. In situations like that I have just used a pointer instead of the reference, all this hassle is just not worth it. Cheers Paavo |
Paavo Helde <myfirstname@osa.pri.ee>: Dec 09 05:08PM +0200 On 9.12.2016 16:23, Ralf Goertz wrote: > big with only a few bits of information actually changing. Therefore, I > try to only make those parts variable and keep the rest const & as in > the example in the OP to avoid copying all the big stuff. My solution basically works around this design and actually changes the const references. If this is not what you wanted, then you should just simply define an assignment operator which only changes the needed pieces: #include <iostream> struct X { const int & cr; int var; X(const int &cr_): cr(cr_), var(0) {} X child() { X ret(*this); ret.var++; return ret; } X& operator=(const X& other) { var = other.var; return *this; } }; int main() { int k = 42; X x(k); x = x.child(); std::cout<<x.var<<std::endl; } |
Ralf Goertz <me@myprovider.invalid>: Dec 09 04:37PM +0100 Am Fri, 09 Dec 2016 17:08:10 +0200 > var = other.var; > return *this; > } Hm, how come that this->cr is still k? Just because the left side of = must have existed before? But then this would be some weired assignment, wouldn't it? int k(42), j(4711); X x(k), y(j); x=y; Now x.cr would still be k, right? |
Paavo Helde <myfirstname@osa.pri.ee>: Dec 09 05:46PM +0200 On 9.12.2016 17:37, Ralf Goertz wrote: >> } > Hm, how come that this->cr is still k? Just because the left side of = > must have existed before? Assignment indeed means that the assigned object already exists before. If it does not, then you have a constructor, not assignment. > X x(k), y(j); > x=y; > Now x.cr would still be k, right? Right. The assignment is weird because references cannot be reseated. I thought this is what you wanted ("keep the rest const [...] to avoid copying all the big stuff"). The destructor+placement new trick works around this and actually reseats the references. It is up to you to decide which behavior you need. Cheers Paavo |
kushal bhattacharya <bhattacharya.kushal4@gmail.com>: Dec 08 09:08PM -0800 i have tried making the console input in different thread but there's some data miscrepencies going on in other words when i ruin different threads using console input one thread works fine but the other thread shows segmentation fault .Could u please tell me what is the real issue behind this ? why am i getting this type of behaviour ? |
"Öö Tiib" <ootiib@hot.ee>: Dec 08 11:20PM -0800 On Friday, 9 December 2016 07:08:54 UTC+2, kushal bhattacharya wrote: > using console input one thread works fine but the other thread > shows segmentation fault .Could u please tell me what is the real > issue behind this ? why am i getting this type of behaviour ? The real reason for such misbehavior is that there are number of programming defects in your code that are probably related to synchronization of threads. |
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