Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
schnarf
Jun 1, 2002
I WIN.
Could you use enable_if and is_base_of to have the templated copy constructor be skipped when T is any class that derives from Base?

Adbot
ADBOT LOVES YOU

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Dicky B posted:

I assumed that in cases where an explicit declaration is available it would take priority over a template method during overload resolution.

This is actually true, but only if the template instantiates to the same thing as the non-template.

TasteMyHouse
Dec 21, 2006

rjmccall posted:

This is actually true, but only if the template instantiates to the same thing as the non-template.

if it doesn't, does the template always have priority, or is it undefined, or what?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
There's this big huge section about overload resolution in the standard, but basically, and glossing over a lot of details:
1. For every function template, use template argument deduction to try to come up with a minimal specialization that makes the argument types match the parameter types. Ignore any function template for which this fails.
2. Now that you have a bunch of candidates with concrete signatures, try to initialize all the parameters with the corresponding arguments. Ignore any candidate for which this fails; otherwise, remember what you had to do to initialize all those parameters.
3. If there are multiple viable candidates, try to find a candidate that's better than all the others.
3a. A cannot be better than B if the conversion sequence needed to initialize the nth parameter of A is worse than the sequence needed to initialize the nth parameter of B. Otherwise, A is better than B if
3b. any of the sequences for A is better than the corresponding sequence for B, or
3c. A is not a template specialization and B is, or
3b. A and B are both template specializations and A's template is more specialized than B's, which is based on this whole other complicated set of rules.

ETA: So applying this to the current problem, template argument deduction (1) makes the constructor have parameter type 'const Derived &'. An lvalue of type 'const Derived' can be passed to both 'const Derived &' and 'const Base &', so both candidates survive (2). The conversion sequence of 'const Derived' -> 'const Derived' is better than the conversion sequence of 'const Derived' -> 'const Base', so (3b) says the template specialization is better. If you repeated this with an argument that's an lvalue of type 'const Base', TAD gives the template spec a parameter of type 'const Base &', so (3c) is required to break the tie.

ETA more: This all forms the core of a pretty convincing argument against "unrestricted function templates": template argument deduction works too well, and the function template tends to grab all the calls, so it gets really hard to ever overload it.

rjmccall fucked around with this message at 07:08 on Oct 9, 2011

TasteMyHouse
Dec 21, 2006

rjmccall posted:

This all forms the core of a pretty convincing argument against "unrestricted function templates": template argument deduction works too well, and the function template tends to grab all the calls, so it gets really hard to ever overload it.

by "unrestricted function templates" do you mean templates without concepts?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
I mean templates which accept essentially arbitrary arguments like this and that don't have some sort of enable_if guard on them.

KiloVictorDongs
Apr 12, 2007
SOME PIG
Okay, can someone help me understand what's going on in the following block?

code:
map < RWDate, map < RWCString, map < int,int > > > & mpWk = m_mapActualExp[uType];
        map < RWCString, map < int,int > > & mpLNR = mpWk[endDate];
	map < int,int > & mapLT = mpLNR[lType];
	mapLT[lTerm] += (int) numOfExpiringLeases;
When I start from scratch, the first thing I'll try to do create a week map that contains the data from the ActualExp map (accessed by uType). Each entry in the week map will have an associated LNR map, and each entry in the LNR map will have an associated LT map. For each lTerm in the LT map, we...create a new int? Increment an int that gets created for each lease term? I'm not sure what that last line is doing.


Edit: VV Thanks, that helped. VV

KiloVictorDongs fucked around with this message at 21:49 on Oct 11, 2011

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
It's just pointlessly spelling out all the intermediate values in m_mapActualExp[uType][endDate][lType] += (int) numOfExpiringLeases;.

If that's not meaningful to you, I don't think anyone here is going to help.

ETA: unless you're confused about what the += operator does, in which case you need to read a book.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
I'm looking for any suggestions on using the preprocessor to do some conditionally-compiled debug information. Are there some mature systems for this, or anything that you do to conditionally log in your code?

In other languages, I'm not so performance-bound so I usually just create a log class, or use something like log4j or log4n to log messages at different log levels. I'm wondering if I'm really freaking out in trying to conditionally compile it in, since I think a branch predictor should take care of things, and I don't think this code will ever get to some profane enterprise size where the instruction cache would get clogged. Then again, I could be wrong.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
Any non-brain-damaged compiler is smart enough to just completely drop a conditional block if the condition const-folds to false, and will completely drop a function call if the function is inlined, does nothing, and the parameter passing is operation-free (i.e. no copies).

shrughes
Oct 11, 2008

(call/cc call/cc)
Yeah but conditionally compiling debug messages is completely easy. For example, just define a debugf function for debug messages and then in release mode, omit the definition and instead #define debugf(...) ((void)(0)).

That's a better idea than some conditional thing because.. you're going to have a macro expand to a conditional expression? That's more crazy than having a function that's replaced by a macro that expands to nothing.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

shrughes posted:

Yeah but conditionally compiling debug messages is completely easy. For example, just define a debugf function for debug messages and then in release mode, omit the definition and instead #define debugf(...) ((void)(0)).

That's a better idea than some conditional thing because.. you're going to have a macro expand to a conditional expression? That's more crazy than having a function that's replaced by a macro that expands to nothing.
The reason for doing it as a conditional thing is that, I believe, you can't do '...' as a parameter list for a #define macro.

So having an inline
code:
#ifdef DEBUG
inline void DEBUGF(char *str,...) {
 //deal with it through vfprintf or whatever.
}
#else
inline void DEBUGF(char *str,...) {}
#endif
... is more flexible (assuming that one of those sort of function will actually compile away to nothing). There is a workaround with a #define and one of those functions, that will compile it away to nothing while still working with the flexible parameters syntax, in case it wouldn't already compile to nothing.

The alternative to that, which I have seen people use, is to have DEBUGF1, DEBUGF2, DEBUGF3 etc. defined so as to support more parameters, but that's horrible to use.

shrughes
Oct 11, 2008

(call/cc call/cc)

roomforthetuna posted:

The reason for doing it as a conditional thing is that, I believe, you can't do '...' as a parameter list for a #define macro.

Sure you can.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

shrughes posted:

Sure you can.
Hm, so you can. You couldn't in 2001! How does that work? I can't find a document explaining how you get at variable preprocessor arguments. (Not that you'd need to for this, you could make it an inline function when you want it to exist and a #define when you don't, I'm just curious how it's done.)

vvvv Ah, so no getting at them individually within the #define. That makes more sense.

pseudorandom name
May 6, 2007

#define debug_printf(format, ...) printf(format, __VA_ARGS__)

Google for "variadic macros"

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Also, variadic functions will usually not compile away to nothing.

That Turkey Story
Mar 30, 2003

Variadic macros are a C99 feature that is also now a C++11 feature. Lots of compilers that support them in C also supported them in C++03 as an extension. Microsoft's compiler has supported variadic macros for a quite a few releases in C++ mode IIRC even though they don't officially try to fully support C99. This is just a warning I guess if you are concerned about having truly standard C++03 code.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
Even if you're dealing with a compiler that can't do that, parameter lists enclosed in () only count as one parameter in macros. It looks kind of awkward but it works.

i.e.:
code:
#ifdef NDEBUG
#define DPRINTF(p) ((void)(0))
#else
#define DPRINTF(p) dprintf p
#endif

...

DPRINTF(("my format %i\n", 1));

Good Will Punting
Aug 30, 2009

And as the curtain falls
Just know you did it all except lift weights
I need a (paid, good) tutor for a Data Structures course. My teacher is mediocre and the material is becoming a little too difficult for me to piece together myself without driving myself up a wall. I need someone who knows their poo poo and would be able to answer the abidance of questions I have every week after looking at our sample code and lectures.

It's entirely C++, which is why I asked in this thread. Anyone have any suggestions where I could find someone? Some other web community, maybe? I'm going to ask at my school but I figured I'd see if anyone here had any suggestions.

TasteMyHouse
Dec 21, 2006
you can just ask questions here and we'll answer them for free. :P

That Turkey Story
Mar 30, 2003

TasteMyHouse posted:

you can just ask questions here and we'll answer them for free. :P

This. Don't worry about asking lots of questions. As long as you are not asking us to do your homework for you, we will gladly help you out. Responses are usually fairly quick as well.

tractor fanatic
Sep 9, 2005

Pillbug
I will do your homework for you for Packers season tickets.

baby puzzle
Jun 3, 2011

I'll Sequence your Storm.
I'm way too baller for your free help.

Good Will Punting
Aug 30, 2009

And as the curtain falls
Just know you did it all except lift weights

tractor fanatic posted:

I will do your homework for you for Packers season tickets.

I hope I'm not still in school in 30 or so years :)

As far as supplementary data structure reading goes, do you guys have suggestions for essential books? My teacher suggests "Data Structures and Other Objects in C++". I also have a copy of Jeffrey Child's "Classes and Data Structures in C++", which is decent but sorta jumps all over much like my lecture notes.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Re: debug logging, I was going to post back asking if there was anything standard or good out there that does a lot of logging already. Doing one preprocessor method would be good for some things, but I wanted something more sophisticated . . .

. . . but then I realized I was being a hypocrite. There is indeed a log4cxx that's in the veins of log4j or log4net. I look at it and think it's too heavyweight. So I guess I need to figure out what the heck I even want to do.

I have a different question about boost threads. I spawn off a bunch of threads and then join them back at main at the end of the program. However, my program doesn't terminate without a break signal. I am assuming I must have missed some thread somewhere. Is there a way to figure out which one easily? Like with gdb? Or is there something more I have to do than join?

nielsm
Jun 1, 2009



GDB can tell you whether you still have threads running, at least.
A rather standard command is thread apply all bt, run a backtrace on every thread.

Joining a thread should be sufficient to free all its resources. You have checked that all of your joins actually complete, right? (Add a print or breakpoint after the last one.)

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

nielsm posted:

GDB can tell you whether you still have threads running, at least.
A rather standard command is thread apply all bt, run a backtrace on every thread.

Joining a thread should be sufficient to free all its resources. You have checked that all of your joins actually complete, right? (Add a print or breakpoint after the last one.)

Thanks for the gdb operation. I'll try that tonight. I thought all my threads joined okay, but I'm assuming a join is a blocking operation here. Is there any reason it wouldn't?

All the of threads I run are stored in objects with a common interface, and I basically expose a join method for them to call the join on their internal threads if need be; some of them don't have a thread so they just return back. I put all these in a container and just iterate the whole mess, calling join one-at-a-time. Before doing this, I've already gone through and basically polled that each one has signalled they exited their main run body; I suppose a wait-notify system would be better blablabla. But at the point of joining I don't see it get caught up. So there's probably some dingleberry thread elsewhere.

Thom ZombieForm
Oct 29, 2010

I will eat you alive
I will eat you alive
I will eat you alive
I am a new C++ person. I use the newest version of Xcode. I am moving into file input/output. I can't open files however, because the program can't find my file. First thought was that the file I created was not in the correct directory. I tried moving it to every possible directory, the program still can't see it. What gives?

- Inside my project folders, there are no "debug" folders.
- I place the data file to be read inside the project directory.

TasteMyHouse
Dec 21, 2006
Try supplying an absolute filename rather than a relative one. You can also see what the working directory of your program is with the function "getcwd()" as demonstrated here
e: changed link to use PATH_MAX

TasteMyHouse fucked around with this message at 22:11 on Oct 12, 2011

Thom ZombieForm
Oct 29, 2010

I will eat you alive
I will eat you alive
I will eat you alive
Cool, so there is a debug folder, just in a totally different place. I got it working thanks to you. Problem: solved!

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

Progression Please posted:

Cool, so there is a debug folder, just in a totally different place. I got it working thanks to you. Problem: solved!

Despite everything working, I thought I'd add to double check the delimeters in your strings. If you're doing "C:\this\that\nother thing" those slashes are going to be interpreted as "C:\[tab]his[tab]hat[newline]other thing" unless you put another slash in front of them.

TasteMyHouse
Dec 21, 2006

Rocko Bonaparte posted:

Despite everything working, I thought I'd add to double check the delimeters in your strings. If you're doing "C:\this\that\nother thing" those slashes are going to be interpreted as "C:\[tab]his[tab]hat[newline]other thing" unless you put another slash in front of them.

He mentioned that he was using X Code, so he's on OS X, not Windows.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

TasteMyHouse posted:

He mentioned that he was using X Code, so he's on OS X, not Windows.

Well that's what I get. :(

Regarding the gdb thread checking, I ran it and found all my threads were still alive. So I checked and found that I wrote all the code to join up the threads, but didn't actually have it hooked up anywhere it would get run. So that was easy.

I'm starting to reign in most of the memory leaks in my program. I'm trying to make some sense of what valgrind considers as "possibly lost." The FAQ kind of stinks:

quote:

"possibly lost" means your program is leaking memory, unless you're doing funny things with pointers. This is sometimes reasonable. Use --show-possibly-lost=no if you don't want to see these reports.
These losses are coming out of middleware so it becomes quite the battle to make sense of what's going on. What would be some examples of "funny things with pointers?" I have the source to pore over so I can see what they're thinking and try to decide if it comes down to how I'm using the libraries. A lot of that is how I took care of true leaks.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
I would guess that valgrind can find a pointer to the interior of the allocation, but not to the start of the allocation. It's possible to do that and still know how to re-derive the start but valgrind is right to be suspicious. (operator new[] actually does this implicitly, but I assume valgrind knows about that and special-cases it somehow)

More devious tricks, like storing the only pointer to an allocation as a relative offset instead of an absolute value, would probably just get reported as "definitely lost".

Ziir
Nov 20, 2004

by Ozmaugh
I have a program that takes a command line argument which should be an integer (e.g., ./program 42), and I need a way to ensure that an integer was entered, else it should print an error. How do I do that?

nielsm
Jun 1, 2009



Ziir posted:

I have a program that takes a command line argument which should be an integer (e.g., ./program 42), and I need a way to ensure that an integer was entered, else it should print an error. How do I do that?

code:
int main(int argc, char *argv[])
{
  /* code goes here */
  /* ... */
  return zero_on_success;
}
argc is the number of commandline arguments, argv is an array of char-pointers to each argument, with argv[0] being the name of the executable itself, argv[1] being the first argument, and so on.
Since argc counts the number entries in the argv array, when argc is 1 you have just the name of your executable and zero arguments, when it is 2 you have your executable name and one argument, and so forth.
You should now be able to answer your own question.

TasteMyHouse
Dec 21, 2006
erm, not quite what he's asking...

Ziir -- if you take the string in the argv array that corresponds to the argument you're talking about and use it to initialize a stringstream object, you can attempt to extract formatted data from the stringstream, and if the extraction fails, you know that the argument is not an integer. like this:

code:

#include <sstream>
#include <iostream>
void yell_at_user();
int main(int argc, char* argv[])
{
	if(argc==1)
	{
		yell_at_user();
		return -1;
	}

	std::stringstream ss(argv[1]);
	int an_integer;
	ss>>an_integer;

	if(ss.fail())
	{
		yell_at_user();
		return -2;
	}
	else
	{
		std::cout<<"hey! good job. int was: "<<an_integer<<std::endl;
	}
}
void yell_at_user()
{
	std::cout<<"usage: ./program <integer>\n";
}

pseudorandom name
May 6, 2007

TasteMyHouse posted:

erm, not quite what he's asking...

Ziir -- if you take the string in the argv array that corresponds to the argument you're talking about and use it to initialize a stringstream object, you can attempt to extract formatted data from the stringstream, and if the extraction fails, you know that the argument is not an integer. like this:

pre:
$ ./wrong 10asdf
hey! good job. int was: 10

TasteMyHouse
Dec 21, 2006
oh drat. What's the best way to do this without boost, then? I'm actually curious myself now. I guess you could just check if eof is set as well after extracting the int?

Adbot
ADBOT LOVES YOU

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

pseudorandom name posted:

pre:
$ ./wrong 10asdf
hey! good job. int was: 10
Which is to say, it depends how picky you want to be. Do you want "10asdf" to count as an integer? Does "10 " (with a space after it) count as an integer? A space before? Must the string contain nothing but numeric characters? Can it have a preceding '-' for negative integers?

This is why designing a program is difficult, and programming a thing to someone else's inadequately specific design is worse.

Edit:

quote:

oh drat. What's the best way to do this without boost, then? I'm actually curious myself now
You can use sscanf and some trickery, like using %d%s as your format string and making sure either only one parameter was read, or the second parameter is zero length (not sure which way it would pan out, and don't actually use plain %s because that could lead to buffer overflow - stick a max length in there). That would be if whitespace is okay and to be ignored. If not that, you do something where you check it character by character to make sure there are only valid characters in the string, then only turn it into an integer by whatever method you prefer if it passed that test.

Edit2: You might also want to make sure it's not too many digits for the number to fit into an integer, if you're really wanting to be anal about input value checking.

roomforthetuna fucked around with this message at 02:19 on Oct 14, 2011

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply