Friday, February 12, 2016

Digest for comp.lang.c++@googlegroups.com - 25 updates in 7 topics

Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 12 12:49AM

How to subscribe to a button press event in my C++ GUI lib, "neogfx":
 
 
button1.pressed([]() { /* do stuff */ }); // simplicity
 
 
https://github.com/FlibbleMr/neogfx/
 
/Flibble
Christian Gollwitzer <auriocus@gmx.de>: Feb 12 10:24AM +0100

Am 12.02.16 um 01:49 schrieb Mr Flibble:
> How to subscribe to a button press event in my C++ GUI lib, "neogfx":
 
> button1.pressed([]() { /* do stuff */ }); // simplicity
 
nice, but still there are three sets of parenthesis that look gibberish.
Compare with Tcl/Tk
 
button .b1 -command { puts "You pressed me" }
 
which creates a button and associates the command with it. This is one
of the times where a preprocessor macro wouldn't be too bad.
Unfortunately CPP is a really stupid one.
 
In fact, a fully functional program in Tcl/Tk is three lines:
 
package require Tk
button .b -text "Press me" -command { tk_messageBox -message "You
pressed me!" }
pack .b
 
I have yet to see another GUI library/language that can beat (or come
close to) this conciseness.
 
> https://github.com/FlibbleMr/neogfx/
 
Another general comment. It is impressive what you have achieved so far.
I don't wnt to discourage you, but for a full fledged cross-platform
widget set which I would consider in a GUI project, there is still a
long way to go. One thing is platform integration. You seem to draw the
widget elements completely on your own using OpenGL. This works now, but
soon your widgets will look old-fashioned, because the design of
computer interfaces follows fashion. Just run anything from before Win7
and you'll immediately understand. For this reason, the established
widget sets use the native widgets under Windows and Mac OSX. Of course
this requires many compromises, because not every option is supported
everywhere and a big pile of work is required to achieve a common API
for all supported systems. There is a somewhat intermediate solution by
drawing your own widgets, but calling APIs which darw parts of teh
native elements upon request. QT works this way, for instance, and ttk
(the themable version of Tk).
 
On Linux (or X11) it is even worse, there is no native widget set
available. You'll have to constantly rewrite your library in order not
to fall out of fashion, though the fashion is not so strong as on the
other OSes. on OSX, in particular, if it doesn't look native (read: like
any recent app from Apple) noone will buy it.
 
That's just my 2 sausages.
 
Christian
leigh.v.johnston@googlemail.com: Feb 12 05:28AM -0800

Once I have implemented all the basic widgets I intend to move their drawing code into a default skin. Other skins will be available and there is no reason you couldn't add a skin that used native OS widget drawing helper functions so I don't believe my GUI lib will suffer from becoming outdated looking.
 
/Flibble
scott@slp53.sl.home (Scott Lurndal): Feb 12 01:48PM

>How to subscribe to a button press event in my C++ GUI lib, "neogfx":
 
> button1.pressed([]() { /* do stuff */ }); // simplicity
 
I'd much rather register a callback function. Lambda's
can impair readability, maintainability and modularity.
 
Most cases where I program a button press event, it requires
dozens of lines of code - not suitable for a lambda.
 
An example (using GTK2):
 
g_signal_connect(e_drawarea, "key-press-event",
G_CALLBACK(keypress), this);
 
 
gboolean
c_env::keypress(GtkWidget *w, GdkEventKey *event, gpointer data)
{
c_env *ep = (c_env *)data;
 
return ep->do_key(event);
}
 
/**
* Handle a key press event within the drawing area for this environment.
*
* @param event The key press event descriptor
* @returns TRUE to stop other handlers for this event, FALSE to propogate
*/
gboolean
c_env::do_key(GdkEventKey *event)
{
s_screen_pos *spp = &e_kbc;
s_page *pp = &e_pages[spp->sp_page];
 
if (pp->p_keyboard_mode == KM_TRANSMIT) {
/*
* Ignore the key, unless it is the RCV key.
*/
if (event->keyval == GDK_F11) {
pp->p_keyboard_mode = KM_RECEIVE;
e_xmit_handler->receive_mode();
update_statusline();
goto leave;
}
gdk_beep();
goto leave;
}
pp->p_keyboard_mode = KM_LOCAL;
 
if ((event->keyval == GDK_Shift_L)
|| (event->keyval == GDK_Shift_R)) {
goto leave;
}
 
... 300 additional lines elided.
 
leave:
if (e_pixmap_dirty) expose(e_drawarea, &e_exposeall);
return TRUE;
}
leigh.v.johnston@googlemail.com: Feb 12 05:57AM -0800

You are not forced to use a lambda you can use anything convertible to a std::function which includes ordinary callback functions however I disagree with your view re lambdas: embrace modern C++.
Luca Risolia <luca.risolia@linux-projects.org>: Feb 12 03:39PM +0100

On 12/02/2016 14:48, Scott Lurndal wrote:
> An example (using GTK2):
 
> g_signal_connect(e_drawarea, "key-press-event",
> G_CALLBACK(keypress), this);
 
that's ugly to say the least.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 12 02:45PM

On 12/02/2016 13:48, Scott Lurndal wrote:
> if (e_pixmap_dirty) expose(e_drawarea, &e_exposeall);
> return TRUE;
> }
 
The problem here isn't my lambda but the fact that you have a 300 line
function. Ever heard of functional decomposition? Functions can call
other functions! Break it up mate (and embrace modern C++ and lambdas).
 
/Flibble
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 12 04:41PM +0100

On 2/12/2016 3:39 PM, Luca Risolia wrote:
 
>> g_signal_connect(e_drawarea, "key-press-event",
>> G_CALLBACK(keypress), this);
 
> that's ugly to say the least.
 
Yes, especially with the stringly typed event id.
 
 
Cheers,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 12 04:43PM +0100

On 2/12/2016 3:45 PM, Mr Flibble wrote:
 
> The problem here isn't my lambda but the fact that you have a 300 line
> function. Ever heard of functional decomposition? Functions can call
> other functions! Break it up mate (and embrace modern C++ and lambdas).
 
Seconded.
 
 
Cheers,
 
- Alf
scott@slp53.sl.home (Scott Lurndal): Feb 12 04:39PM


>> g_signal_connect(e_drawarea, "key-press-event",
>> G_CALLBACK(keypress), this);
 
>that's ugly to say the least.
 
Eye of the beholder. Less ugly than a 300 line lambda.
scott@slp53.sl.home (Scott Lurndal): Feb 12 04:42PM


>The problem here isn't my lambda but the fact that you have a 300 line
>function. Ever heard of functional decomposition? Functions can call
>other functions! Break it up mate (and embrace modern C++ and lambdas).
 
It's a big switch on the keyval. Sure, could use a lookup table and
call a function, but why? It works. It's easy to maintain. And it was
written a long long time ago for X11R4 and ported later to GTK2.
Christopher Pisz <nospam@notanaddress.com>: Feb 12 10:22AM -0600

Has anyone implemented an xpath equiv for json in C++?
 
ermehgerd, it's killing me. I cannot believe there is not already some
library that handles this.
 
I found jsoncpp, but it crashes when you give it a path of more than 1
level. Can't find anything else
 
 
 
 
--
I have chosen to troll filter/ignore all subthreads containing the
words: "Rick C. Hodgins", "Flibble", and "Islam"
So, I won't be able to see or respond to any such messages
---
Daniel <danielaparker@gmail.com>: Feb 11 06:05PM -0800

On Thursday, February 11, 2016 at 5:42:06 PM UTC-5, Wouter van Ooijen wrote:
> > /Flibble
 
> Who? Fibble? The nonsense guy makes a remark that makes some sense?
 
It's Flibble, if you please.
 
Daniel
Cholo Lennon <chololennon@hotmail.com>: Feb 12 09:36AM -0300

On 02/11/2016 05:48 PM, Scott Lurndal wrote:
>> So instead of setter, we would always pass the object and the new value.
 
> Well, I personally have no problem with getters and setters. I don't
> see a need for a specific naming convention, however.
 
I agree with you.
 
Also IMO a getter/setter can have a non trivial implementation (i.e.
provide a synchronous access to data). Another advantage over public
data members is that calls to them can be deferred in time with
std::function/std::bind.
 
Regards
 
--
Cholo Lennon
Bs.As.
ARG
scott@slp53.sl.home (Scott Lurndal): Feb 12 01:39PM

>provide a synchronous access to data). Another advantage over public
>data members is that calls to them can be deferred in time with
>std::function/std::bind.
 
They also provide for the abstraction of the underlying data type,
which then can be changed without changing the clients of the public
class interface.
Bo Persson <bop@gmb.dk>: Feb 12 05:12PM +0100

On 2016-02-11 18:15, K. Frank wrote:
 
> Having said that, I don't think that getters/setters are
> evil -- they're just something of a nuisance, especially
> in simple settings.
 
They become evil when people write code like
 
pd.setAge(pd.getAge() + 1);
 
and believe they have done something proper.
 
 
Bo Persson
Christian Gollwitzer <auriocus@gmx.de>: Feb 12 10:29AM +0100

Am 11.02.16 um 21:28 schrieb Mr Flibble:
> ... you muthafucking cunt.
 
Swearing is healthy. It relieves pain
https://en.wikipedia.org/wiki/Hypoalgesic_effect_of_swearing but it
works best if you are not used to it :P
 
It also helps keeping some people from discussion threads.
 
Christian
JiiPee <no@notvalid.com>: Feb 12 03:16PM

On 12/02/2016 09:29, Christian Gollwitzer wrote:
> works best if you are not used to it :P
 
> It also helps keeping some people from discussion threads.
 
> Christian
 
Starting fights/fighting on the streets also relieves pain (as adrealine
is released), so according to your logic we should all start to fight? :)
ram@zedat.fu-berlin.de (Stefan Ram): Feb 12 12:36AM

> int age;
>};
>So how to change that name without a setter?
 
This depends on the definition of »setter«.
ram@zedat.fu-berlin.de (Stefan Ram): Feb 12 01:23PM

>Yes. The `Container` class should instead be like
 
I tried to build a simplified model of the UB:
 
#include <iostream>
#include <ostream>
#include <string>
 
struct wrapper
{ const std::string & value;
wrapper( const ::std::string & string ): value( string ) {} };
 
int main() { wrapper x( "" ); ::std::cout << x.value << '\n'; }
 
The above program should have UB for reasons similar as in
the OP.
 
But the program below should not have UB anymore, due to the
variable »s«.
 
...
 
int main()
{ ::std::string s = "";
wrapper x( s ); ::std::cout << x.value << '\n'; }
 
However, we get UB again when we change the type of »s«:
 
...
 
int main()
{ char const * s = "";
wrapper x( s ); ::std::cout << x.value << '\n'; }
 
While the result is the same, I prefer a style that avoids
the char-*-strings from the language C, so (also no UB):
 
...
 
using namespace ::std::literals;
 
int main()
{ ::std::string s = ""s;
wrapper x( s ); ::std::cout << x.value << '\n'; }
 
But even without a conversion, we can reintroduce UB easily
again (due to a literal also having a temporary value):
 
...
 
using namespace ::std::literals;
 
int main()
{ wrapper x( ""s ); ::std::cout << x.value << '\n'; }
 
.
Christof Warlich <christof.warlich1@gmail.com>: Feb 12 03:17AM -0800

Hi,
 
I'm really desperate to understand why the following code does not work as expected:
 
#include <functional>
#include <iostream>
struct Container {
Container(const std::function<void()> &funtor): _functor(funtor) {}
const std::function<void()> &_functor;
};
struct Functor {
Functor(int i): _i(i) {}
void operator()() {
std::cout << _i << std::endl;
}
int _i;
};
int main() {
Functor funtor(42);
Container container(funtor);
container._functor();
return 0;
}
 
It prints 0 instead of 42, and I really don't understand why.
 
It works fine when I store the std::function object as a copy instead of just storing a reference in my container, i.e. when I remove the ampersend from line 5. But that's not an option because I finally want my operator() to return a result in one of the functors member variables.
 
I'm obviously having some severe misconception w.r.t. the lifetime of the reference: Can anyone help me to understand what's really going on here?
 
Thank you so much,
 
Chris
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 12 12:52PM +0100

On 2/12/2016 12:17 PM, Christof Warlich wrote:
> return 0;
> }
 
> It prints 0 instead of 42, and I really don't understand why.
 
It could just as well have crashed; it's Undefined Behavior.
 
You're binding a reference to a temporary in the line I've marked "!!".
The temporary's lifetime extends to the semicolon in that line. From
then on you have a /dangling reference/.
 
Note also that the convention with leading underscore for data member
names is in direct conflict with the rules for reserved names. There are
zillion naming conventions to choose from. No need to choose the worst.
 
 
Cheers & hth.,
 
- Alf
Christof Warlich <christof.warlich1@gmail.com>: Feb 12 04:22AM -0800

Am Freitag, 12. Februar 2016 12:53:11 UTC+1 schrieb Alf P. Steinbach:
> > Container container(funtor); //!!
...
 
> You're binding a reference to a temporary in the line I've marked "!!".
> The temporary's lifetime extends to the semicolon in that line. From
> then on you have a /dangling reference/.
 
Again, just to fully understand: Is the temporary created because the compiler silently converts my Functor object to a (temporary) std::function<void()> object while passing to my container?
 
 
> Note also that the convention with leading underscore for data member
> names is in direct conflict with the rules for reserved names. There are
> zillion naming conventions to choose from. No need to choose the worst.
 
Ok, I'll happily take this advice as well :-).
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 12 02:14PM +0100

On 2/12/2016 1:22 PM, Christof Warlich wrote:
 
> Again, just to fully understand: Is the temporary created because the
> compiler silently converts my Functor object to a (temporary)
> std::function<void()> object while passing to my container?
 
Yes. The `Container` class should instead be like
 
struct Container
{
function<void()> functor_;
 
Container( function<void()> functor )
: functor_( move( functor ) )
{}
};
 
An alternative is to accept whatever type of functor the client code
supplies, without invoking the (possibly costly for some types) type
erasure of `std::function`, e.g.
 
template< class Func >
struct Container
{
Func functor_;
 
Container( Func functor )
: functor_( move( functor ) )
{}
};
 
template< class Func >
auto make_container( Func f )
-> Container<Func>
{ return Container<Func>( move( f ) ); }
 
In addition to possible improved efficiency for bloated but movable
functors, this has the general advantage of not throwing away type
information. Which in itself can also improve efficiency, because it
allows the compiler to generate inline code for a call on class type
functor. However, before being swayed by such arguments I'd measure, and
most likely (and yes, I've made that decision a few times) I wouldn't
care but just use std::function for simplicity and /clarity/.
 
 
Cheers & hth.,
 
- Alf
Jerry Stuckle <jstucklex@attglobal.net>: Feb 11 07:02PM -0500

On 2/11/2016 4:35 PM, Vir Campestris wrote:
> to argue with you about it.
 
> But for the avoidance of doubt you are wrong.
 
> Andy
 
No, I'm not. I'm telling you they don't perform unnecessary tests.
They know a NAND gate in a design is a NAND gate. They don't need to
test to see that it works. But they do test the circuit the NAND gate
is in. If the circuit works, then they know the NAND gate is working.
 
And no, I didn't speak to their engineers when the 7473 was in common
use - I used that as an example. I spoke with them much more recently.
And since my original background was EE, I spoke with them on an equal
level - which is why companies call me back. I understand both the
hardware and the software.
 
So yes, I HAVE been working closely with "those who are". And I
understand how they work.
 
But you've just once again proven how dense you are.
 
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
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: