|
You cannot say that this:
std::vector<RSS_struct>
is as concise as this:
RSSVector
And yes, you can throw in a "using std::vector" declaration and simplify a bit, but the non-typedef'd version is still longer. And really, how is a using declaration fundamentally different than a typedef? They both make code prettier by giving up a little bit of explicitness.
I tend to find that the angle brackets are unpleasant to look at, as well.
I'm not saying that typedefs are necessary. Nor am I saying that they should be used most of the time. But you said they make code unreadable, and I believe that's clearly not the case.
|
|
|
|
|
Curi0us_George wrote:
You cannot say that this:
std::vector
is as concise as this:
RSSVector
No, but it has the advantage of being C++. I know what it means when I read it.
Curi0us_George wrote:
And yes, you can throw in a "using std::vector" declaration and simplify a bit
Seriously, who on earth DOESN'T do that ?
Curi0us_George wrote:
And really, how is a using declaration fundamentally different than a typedef?
It's valid C++, I know right away that it's lurking somewhere when I see vector without the std in code. I don't need to go looking for the using statement to decipher the vector variable. Not so your typedef.
Curi0us_George wrote:
I tend to find that the angle brackets are unpleasant to look at, as well.
That's your call. I find they make it easy for me to scan STL code to get to the bits I need to know what is going on.
Curi0us_George wrote:
But you said they make code unreadable, and I believe that's clearly not the case.
You're clearly wrong. My original statement was that they CAN make code unreadable. I've downloaded code, I think here from CP, and spent half a day deciphering it because it used a LOT of different STL container instances, and the typedef names they used were plain awful. It was like looking at a different programming language altogether.
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
typedef is part of the C++ language, just like the using declaration. It is perfectly valid C++, and Stroustrup himself gave similar examples of when one might use typedefs. He said that "unsigned char" is really too long and unwieldy to use, so we might define "uchar". Same with vector<sometype>. It's often convenient to use a shorter synonym.
As for knowing that "vector" refers to "std::vector", you are wrong. You do not know when you see a vector reference with no namespace qualifier, that the vector is a std::vector. If you did, then C++ namespaces would be meaningless. Typically your assumption would be correct, but not always.
"You're clearly wrong. My original statement was that they CAN make code unreadable."
I don't really think I'm wrong. You said, "I would advise against this, it makes your code unreadable." RSS_vector was a fairly clear typedef. That's all I was saying. Rather than blaming the typedef functionality for poor clarity, blame the poor names. Poorly named classes also lead to poor clarity, but it's not a fault with the feature. It's a fault with the programmer.
|
|
|
|
|
Curi0us_George wrote:
typedef is part of the C++ language, just like the using declaration. It is perfectly valid C++, and Stroustrup himself gave similar examples of when one might use typedefs. He said that "unsigned char" is really too long and unwieldy to use, so we might define "uchar". Same with vector. It's often convenient to use a shorter synonym.
Your first point is valid, and I am well aware that Stroustrup shows the use of typedefs in similar circumstances to those we are talking about. He also makes clear that C++ langauge features were included on the basis of how they could be used well, not excluded based on how they could be abused by the clueless. The designers of C# could have learned from this approach. What I'm saying is that just because you CAN typedef, does not mean you SHOULD. Stroustrup also says that macros should never be used, they are always a sign of a bad design or a bad programmer. A typedef is really not much different to one possible use of a macro, that of creating our own language ( exactly what Stroustrup warned against ), by creating new names for things that already exist.
Curi0us_George wrote:
Typically your assumption would be correct, but not always.
Which makes your comment obviously dumb. Yes, it's entirely possible that it would be referring to some other class called vector, but from my point of view, I'd be forgiven for assuming it was a std::vector, and if every time you see a vector in code you go searching to make sure that it's from namespace std, then I'm afraid you're being overly anal.
Curi0us_George wrote:
Rather than blaming the typedef functionality for poor clarity, blame the poor names. Poorly named classes also lead to poor clarity, but it's not a fault with the feature. It's a fault with the programmer.
And that's what I've said all along, my point is that I've seen code rendered illegible by poor use of a plethora of typedefs, and really at the end of the day it's my opinion that anyone too dumb to read STL code should probably give VB a try. I still don't see how the typedef helps anything, except for the lazy typist, and it still remains that you have to 'learn' the typedefs in a project unless they are so descriptive that they are as long as the thing they replace.
And I really doubt we have any chance of convincing each other, or that we're even 100% on the same page anymore.
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
I don't think my comment about namespaces was dumb, but that's your opinion.
I also still think that typedefs can be useful, but you're right. This isn't going anywhere.
I do acknowledge that poorly named typedefs are a terrible, though.
- Derek
P.S. As for who doesn't use "using std::whatever", I typically don't. I normally use the fully qualified names, partly because I've worked with other classes with identical names before (e.g. vector), but mostly because I end up forgetting which one's I've declared and which ones I haven't. And when I use something new that I've forgotten to declare, the compiler complains. Frustrates me and wastes time. The same thing happens when I cut and paste and forget the using declarations. It typically turns out to be more energy efficient for me to just type the "std::" every time. I suppose I could add "using namespace std" to all of my files, but I consider importing entire namespaces to be poor style.
|
|
|
|
|
Curi0us_George wrote:
I suppose I could add "using namespace std" to all of my files, but I consider importing entire namespaces to be poor style.
I agree 100%. I tend to include and use standard library components in stdafx, so I always know where to go to update my using std:: list. I make it alphabetical, so it's easy to scan.
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
I would agree if the typedef names are cryptic, like the ones used in the STL. Unfortunately typedefs are often used only as abbreviations, and that's the wrong usage, IMHO. If you use descriptive names, like RSSVector, I think it actually makes the code more readable while cutting down on the typing.
What looks better?
std::vector<RSS> m_vector;
void GetVector(std::vector<RSS>& v);
or
RSSVector m_vector;
void GetVector(RSSVector& v);
Regards,
Alvaro
Give a man a fish, he owes you one fish. Teach a man to fish, you give up your monopoly on fisheries.
|
|
|
|
|
Your example is longer than it needs to be, because you can do a using std::vector prior. Having done that, I'd regard the first example as looking better. Which goes to show that it's all a matter of opinion, as I'm sure you were not expecting me to say that
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
OK, perhaps my example wasn't compelling enough. How's this one:
std::map<std::string, std::vector<std::string>*> m_mapNameToFriends;
void GetMap(std::map<std::string, std::vector<std::string>*>& mapNameToFriends);
vs
typedef std::vector<std::string> NameVector;
typedef std::map<std::string, NameVector*> NameToNameVectorPtrMap;
NameToNameVectorPtrMap m_mapNameToFriends;
void GetMap(NameToNameVectorPtrMap& mapNameToFriends);
I'm not expecting to convince you here either, just proving my point that typedefs can be good in good hands.
Regards,
Alvaro
Give a man a fish, he owes you one fish. Teach a man to fish, you give up your monopoly on fisheries.
|
|
|
|
|
You're still using std:: to make things look more complex than they need to.
using std::map;
using std::string;
using std::vector;
map<string, vector<string>*> m_mapNameToFriends;
void GetMap(map<string, vector<string>*>& mapNameToFriends);
See what a huge difference that makes ?
std::map<std::string, std::vector<std::string>*> m_mapNameToFriends;
void GetMap(std::map<std::string, std::vector<std::string>*>& mapNameToFriends);
I vastly prefer this to either example that you gave. I fully accept that my own bad experiences slant my views and make me prefer to have the code tell me what is going on, but the only reason I have a leg to stand on at this point is that you deliberatly obsfucated the code in your example
Christian
I have drunk the cool-aid and found it wan and bitter. - Chris Maunder
|
|
|
|
|
How do you get the coordinates of a control on a dialog relative to the upper-left corner of the dialog? I've tried using the GetClientRect & GetWindowRect functions of the control I want the coords for, but neither returns the right value. Any help is appreciated. Thanks.
- Aaron
|
|
|
|
|
CRect rect;
GetDlgItem(IDC_CONTROLNAME)->GetWindowRect(&rect);
ScreenToClient(&rect);
You should then be able to take the values of rect.
"You know "that look" women get when they want sex? Me neither."
--Steve Martin
|
|
|
|
|
I got it working using GetWindowRect of the control and ScreenToClient of the dialog. Is this the best way to do it?
[EDIT]
Guess I should have refreshed before I posted Thanks for the help though
[/EDIT]
- Aaron
|
|
|
|
|
Off the top of my head.
GetClientRect(): is the rectangular area that represents the area where drawing is to occur, with (0,0) representing the upper left courner of the client area within the window.
GetWindowRect(): is the rectangular area that represents the area where the window is draw in screen coordinates and must be converted to client coordinates to be useful.
Therefore, you need to get the screen coordinates via GetWindowRect() and then convert them to the dialog coordinates via ScreenToClient().
Now is there a better way or a function that does the needed conversion for you? I am not sure, there is one function whose usage is a bit confusing so I keep forgetting its' name and all I remeber (at the moment) is that it converts from one coordinate system to anoghter (a.k.a. client to screen or screen to client). Basicaly, it is less confusing to do it your self (with two simple function calls), than to call some function that (based on the arguments) makes the same function calls.
INTP
|
|
|
|
|
I need to find out the Domain name in which my computer is at the moment not using GetComputerNameEx if possible. How?
|
|
|
|
|
You can use LookupAccountName
<br />
DWORD dwDomain = DNLEN + 1;<br />
char szDomain[DNLEN + 1];<br />
<br />
memset(&szDomain, 0, DNLEN + 1);<br />
<br />
PSID pSid = NULL;<br />
DWORD cbSid = SID_SIZE;<br />
SID_NAME_USE peUse;<br />
<br />
pSid = (PSID)HeapAlloc(GetProcessHeap(), 0, cbSid);<br />
ASSERT(pSid != NULL);<br />
<br />
if (LookupAccountName(NULL, szUserName, pSid, &cbSid, szDomain, &dwDomain, &peUse)) <br />
{<br />
}<br />
<br />
if (pSid != NULL)<br />
HeapFree(GetProcessHeap(), 0, pSid);
This may help you, note that if the computer is not joined to a domain it returns the computer name!
Ant.
|
|
|
|
|
Wait a minute!
what is szUserName as the second parameter?
It look like it wants full domain\user path, but if I knew that I wouldn't need to call this on the first place.
So at the moment I get only computer name as when it's not joined to a domain, but it is.
|
|
|
|
|
Um fair points. However you do not need the full qualifying 'domain\username' you can pass just 'username'.
The reason you get the local machine is probably because the szUserName is a local account name also. You could set the szUserName to a domain account name and this should then find the domain that that account resides.
I wish I'd thought a bit longer before posting this as it is not ideal
Ant.
|
|
|
|
|
Ok. For now I'll use GetComputerNameEx and/or NetGetJoinInformation.
But those are just on 2000, XP and 2003.
<dreaming>
Still would be nice to figure out the domain name on like NT and 98.
</dreaming>
|
|
|
|
|
I need to dump data to my SDI window as I read it from a socket. What's the easiest way to do that ?
Thanks !!
|
|
|
|
|
Stick a RichEdit control in the middle of your window and dump all the input into it?
It's dirty, but it works.
|
|
|
|
|
Can you give me an example of how to add it and how to dump to it ?
Thanks !
|
|
|
|
|
Depends on what framework you are using. Since you referred to "SDI", I assume you're doing MFC or WTL. There are a ton of articles on this site which can should you how to add a RichEdit control to either of those windows. Just look around a bit. (Or check out msdn.)
|
|
|
|
|
How about TextOut() ?
"The pointy end goes in the other man." - Antonio Banderas (Zorro, 1998)
|
|
|
|
|
David
Any example of using TextOut() ?
Thanks !
|
|
|
|
|