15 Dec, 2008, ghasatta wrote in the 1st comment:
Votes: 0
I just came up with this beast while working on a special project and wanted to share. Brownie points if you can look at this without having your brain melt.

(this->*this->function_handlers[packet_type])(this->input_queue.front());


I am invoking a member function via a member function pointer that is stored in a map. Er, that probably didn't help explain things. Anyway, it works! ;)
15 Dec, 2008, Sharmair wrote in the 2nd comment:
Votes: 0
The first this is required for the pointer to member syntax, but I would think the other two are
really unneeded.
(this->*function_handlers[packet_type])(input_queue.front());
15 Dec, 2008, David Haley wrote in the 3rd comment:
Votes: 0
Agree with Sharmair. The original is still pretty comprehensible though. I guess I've just seen much worse. :wink:
15 Dec, 2008, ghasatta wrote in the 4th comment:
Votes: 0
Re Sharmair, thanks, that works too.

Thought I tried that last night but apparently not. Regarding "this->input_queue…", the 'this' pointer may be optional there but it's a style choice to help make it clear where the structure is coming from.
15 Dec, 2008, Davion wrote in the 5th comment:
Votes: 0
Pfft. You're not even using cryptic operator overloading or mind boggling templating. :P
15 Dec, 2008, David Haley wrote in the 6th comment:
Votes: 0
ghasatta said:
Regarding "this->input_queue…", the 'this' pointer may be optional there but it's a style choice to help make it clear where the structure is coming from.

Personally I think that should be indicated otherwise. There are several options:
- if trying to differentiate with global variables, prefix global variables with "g" or something. e.g., gInputQueue. (Actually, I think that's a good idea in general, because it is immediately obvious if a variable is global or not.)
- if trying to differentiate with a static class variable, use the class name, e.g. MyClass::theVariable.
- if trying to differentiate local vs. member variables, mark member variables with something. Some people like putting an m in front, e.g. mInputQueue. I like putting an underscore at the end, e.g. inputQueue_. Again, this is a good idea in general because it is immediately obvious where something is coming from.

In short and IMHO, if you need to use "this" to mark where a variable is coming from, then that is indicative of potential confusion in several places. A name alone in almost all cases should suffice to tell you what you need to know about the variable. Some people go so far as to encode the type itself in the name, for example, miPeopleInRoom to denote the number (int) of people in the room as a member (m) variable. I tend to not do that for various reasons.

Having a convention and sticking to it religiously can dramatically improve the clarity of code. One of my codebase's problems is that in the many years I've been working on it, I have changed styles as I find that some things work better than others. It's interesting actually that you can almost tell when I wrote a segment of code by looking at the style it's written in. :wink:
15 Dec, 2008, ghasatta wrote in the 7th comment:
Votes: 0
Yep I am aware of conventions such as hungarian notation, and so on.

Quote
then that is indicative of potential confusion in several places.

Perhaps. You've given some alternatives but you haven't really given any of these potential reasons. Care to elaborate?

Quote
Having a convention and sticking to it religiously can dramatically improve the clarity of code
I agree, which is why I use my convention ;)
15 Dec, 2008, elanthis wrote in the 8th comment:
Votes: 0
DavidHaley said:
Personally I think that should be indicated otherwise. There are several options:


It's true that using this-> as an indicator is pretty non-standard in C++, but I myself actually kind of like it. I really kind of just prefer that every identifier by qualified without relying on manual naming conventions. Maybe I've just spent too many years working in dynamic languages that essentially force you to do that, though. :)

Quote
Some people go so far as to encode the type itself in the name, for example, miPeopleInRoom to denote the number (int) of people in the room as a member (m) variable. I tend to not do that for various reasons.


These people are lame. The original "hungarian notation" had nothing to do with specifying types in names. The compiler already makes sure you can't misuse a type. The original purpose was to mark information about a variable's data that is not immediately obvious from the type. For example, if you are working on an application that has to deal with SQL queries, you would want to differentiate between strings which are just user input and strings which are supposed to be part of a SQL query, thus making it possible to write static analysis tools that would notice if you tried to concatenate unquoted user-data into one of your strings. Another example might be marking pointer types with whether or not they represent ownership of the object or not. Keep in mind that in those days, standardized C++ did not have even half the features it has today; hence why Microsoft's Win32 APIs still include a lot of cruft like a non-STL string class. Enforcing that kind of type behavior using templates or other useful C++ tricks was not feasible then. The technique is attributed to one of the Microsoft Word developers, but the other doofuses at Microsoft misunderstood the intent and ending up standardizing this huge monstrous type notation that does nothing but make variable names longer, harder to remember, and often just flat out inaccurate when types change but updating every variable name is too tedious.

Quote
One of my codebase's problems is that in the many years I've been working on it, I have changed styles as I find that some things work better than others. It's interesting actually that you can almost tell when I wrote a segment of code by looking at the style it's written in. :wink:


That's true for quite a bit of code out in the wild, too. :)

Personally, I think that if he wants to use this-> to reference member variables and methods, more power to him. It's unorthodox, but there is absolutely no compelling reason to prefer other approaches outside of "less typing." To be perfectly honest, if I were designing C++ from scratch today, I never would have added class scope (but I would have added an automatic class:: or self:: scope).
16 Dec, 2008, Zeno wrote in the 9th comment:
Votes: 0
That's nothing. How about this?
#include <stdio.h>

char
*T="IeJKLMaYQCE]jbZRskc#include <stdio.h>

char
*T="IeJKLMaYQCE]jbZRskc[SldU^V\\X\\|/_<[<:90!\"$434-./2>]s",
K[3][1000],*F,x,A,*M[2],*J,r[4],*g,N,Y,*Q,W,*k,q,D;X(){r [r
[r[3]=M[1-(x&1)][*r=W,1],2]=*Q+2,1]=x+1+Y,*g++=((((x& 7)
-1)>>1)-1)?*r:r[x>>3],(++x<*r)&&X();}E(){A||X(x=0,g =J
),x=7&(*T>>A*3),J[(x[F]-W-x)^A*7]=Q[x&3]^A*(*M)[2 +(
x&1)],g=J+((x[k]-W)^A*7)-A,g[1]=(*M)[*g=M[T+=A ,1
][x&1],x&1],(A^=1)&&(E(),J+=W);}l(){E(–q&&l ()
);}B(){*J&&B((D=*J,Q[2]<D&&D<k[1]&&(*g++=1 ),
!(D-W&&D-9&&D-10&&D-13)&&(!*r&&(*g++=0) ,*
r=1)||64<D&&D<91&&(*r=0,*g++=D-63)||D >=
97&&D<123&&(*r=0,*g++=D-95)||!(D-k[ 3]
)&&(*r=0,*g++=12)||D>k[3]&&D<=k[ 1]
-1&&(*r=0,*g++=D-47),J++));}j( ){
putchar(A);}b(){(j(A=(*K)[D* W+
r[2]*Y+x]),++x<Y)&&b();}t ()
{(j((b(D=q[g],x=0),A=W) ),
++q<(*(r+1)<Y?*(r+1): Y)
)&&t();}R(){(A=(t( q=
0),'\n'),j(),++r [2
]<N)&&R();}O() {(
j((r[2]=0,R( ))
),r[1]-=q) &&
O(g-=-q) ;}
C(){( J=
gets (K
[1]))&&C((B(g=K[2]),*r=!(!*r&&(*g++=0)),(*r)[r]=g-K[2],g=K[2
],r[
1]&&
O())
);;}
main
(){C
((l(
(J=(
A=0)
[K],
A[M]
=(F=
(k=(
M[!A
]=(Q
=T+(
q=(Y
=(W=
32)-
(N=4
))))
+N)+
2)+7
)+7)
),Y=
N<<(
*r=!
-A))
);;}
[/code]

[url=http://www.ioccc.org/2000/anderson.hint]... program is a simple filter that translates ASCII text into semaphore code.[/url]
16 Dec, 2008, David Haley wrote in the 10th comment:
Votes: 0
ghasatta said:
Perhaps. You've given some alternatives but you haven't really given any of these potential reasons. Care to elaborate?

I'm assuming you mean reasons for confusion? Well, here's my favorite: it means that scope is not clear enough from context. Is there another input queue I should be worrying about, that makes me specify "this"?
ghasatta said:
Quote
Having a convention and sticking to it religiously can dramatically improve the clarity of code
I agree, which is why I use my convention ;)

Yes – and yet here you are showing off an example of convoluted C++ syntax. :wink:

There's a reason why prefixing every instance variable with "this->" is unorthodox. Yes, it means less typing, but more importantly, less typing means less characters you need to sift through. Every time you see a dereference, you need to stop to process what's going on. In some cases, it leads to things like the line of code that started this thread.

This kind of terseness is good for many reasons: it means less "useless" information to process (as I said above, context should already be clear). Saving screen space is important because you can see more code at once, and more importantly, you keep lines less wide so you do not have to scroll back and forth or break them manually in the code.

Obviously there are limits (it is excessive to remove all strictly unnecessary whitespace, for example), but generally verbosity for the sake of verbosity is to be avoided as it detracts from the semantic content: the meaning of the code.
0.0/10