raptr_dflo 48 Posting Pro

Hi inner circle, welcome to DaniWeb.

I don't know who Dr. Azalov is, your course instructor perhaps? What part would he disapprove of? Or did you mean the general "asking for help online" part? I'm not going to do your assignment for you, nor (with any luck) is anyone else on this forum. We're here to help you build and improve your programming skills, and lend some pointers and insight on more obscure aspects if we can.

If your course instructor has specifically said you should work out your assignments on your own, then it's up to you to do so. It's not my job to know who's in which class, and what their various restrictions might be. But since I'm still not going to hand over a completed working program, I don't believe it should be a problem.

Now if you need help, you should follow the same procedures as everyone else. Start writing your program, and get as far as you can on your own, then post your code here with specific questions on the parts you can't get working. And read "Read Me: Read This Before Posting A Question" (the clearly-marked sticky-post at the top of the forum).

raptr_dflo 48 Posting Pro

Hi TheFearful,

Nothing to be afraid of here, except maybe frogboy's sarcasm. :)

In the first problem, since you don't actually need to perform any math on the input numbers, they don't need to be integers. You could play the same game, called "happy words" on 4-letter words: "HEAD" is a happy word, "FOOT" is not. Yes you need a loop, and iterating over the character positions in a string is much more obvious than extracting decimal digits from an integer. Does that help?

What is your question regarding the second problem? Actually, I know what the question is already, I can read minds: "why does my estimate suck?" The problem is you've collapsed the need for two loops into one. Simplify your logic by creating a function called estimateCubeRoot() which takes your "a" as an argument and returns your computed estimate of a^(1/3). That function needs a loop inside it which keeps revising the estimate until the difference between successive values is small enough. Then you still need a loop in your main() which provides successive values of a, and prints a, the estimated cube-root returned from your function, and the value computed by the pow() function.

Keep it simple, make functions that do simple logically-grouped things, call those functions when you need them to perform their tasks. This is the first part of "modular programming". In C++, the next part is to create groupings of functions and data into "classes". And related functions into …

raptr_dflo 48 Posting Pro

At line 11, you assign q->next equal to p->next, but p isn't defined. I suspect that what this function is -supposed- to do is append the len new nodes to the end of the list, so you need to initialize p by stepping through the list, starting at ptr, until p->next is NULL.

raptr_dflo 48 Posting Pro

How have you drawn your basic face? With code, on the computer? With charcoal on paper?

What does it mean to "merge the template with a real human face"?

Once you can more clearly state what your program needs to do, it will be more clear how to start writing it.

raptr_dflo 48 Posting Pro

Awesome! Please mark your thread as "solved". :)

raptr_dflo 48 Posting Pro

I can find only one reference to your undeclared constant:

prompt$ pwd
<other path components>/Microsoft DirectX 9.0 SDK (Summer 2004)

prompt$ find Include/ -name \*.h -exec grep IID_IDirect3D3 {} /dev/null \;
Include/d3d.h:DEFINE_GUID( IID_IDirect3D3,            0xbb223240,0xe72b,0x11d0,0xa9,0xb4,0x00,0xaa,0x00,0xc0,0x99,0x3e);

This tells me you need to find that missing d3d.h file to proceed, but I could be wrong.

raptr_dflo 48 Posting Pro

Sorry, incorrect usage, my fault. This should work:

char _schoolInfo[100];
inFile.getline(_schoolInfo, 100);
if (inFile.fail()) {
    cerr << "school info was longer than 100 characters, sorry!" << endl;
    return 1;
}
// make a std::string from the char-array
string schoolInfo(_schoolInfo);
cout << "Test results from: " << schoolInfo << endl;
raptr_dflo 48 Posting Pro

Excellent! Please mark the thread as "solved". :)

raptr_dflo 48 Posting Pro

You have to read the desired line out of the file between the time you open the file and the time you start reading student information out of it, maybe around line 57:

string schoolInfo = inFile.getline();
cout << "Test results from: " << schoolInfo << endl;
raptr_dflo 48 Posting Pro

I think you changed the wrong line. It's hard to say, since the source code didn't get line numbers when you posted it. The "for i" line, not the "for x" line. Here, I'll copy it:

fr << setw(20) << left << "Pavardė" << setw(10) << "Vardas" << left
   << setw(16) << "Įstojimo metai" << "Egzaminu pažymiai" << endl;
for(int i = 0; i < S[i].ImtiKieki() ; i++)
{
    fr << left << setw(20) << S[i].ImtiPavardę() << setw(14) << S[i].ImtiVardą()
       << fixed << right << setw(4) << right << S[i].ImtiĮMetus() << "       |";
    // cycle to print given numbers (students grades), maybe something's wrong here?
    for (int x = 0; x < S[i].ImtiKieki(); x++)
        fr << fixed << right << S[i].ImtiPažymius(x) << " ";
    fr << endl;
}

Line 3 above (not line 8).

raptr_dflo 48 Posting Pro

That's a lot of code to ask us to pore over by hand, rather than doing what was already asked. If you don't know how to use the debugger for your development environment, then start by inserting lines like cout << "Here #1" << endl; into your main(), and see how far it gets before you get the Segmentation Fault. Once you've narrowed it down to a particular function call, you can start outputting more detailed information, and/or inserting output lines within the function.

That said, I started following the flow in main(), looks like sort.MakeEmpty() is fine, but after that, you call this absurd sort.IsFull() function which wastefully allocates and frees a node, just to see if it can. The point of a linked-list is that there is no concept of "full". It can grow until the system runs out of memory, which is what you're in fact testing. Instead, it is more practical simply to allocate the node within the Insert function, and if you fail, return a value that indicates failure. Thus bool InsertItem(args) rather than void InsertItem(args) .

I then looked for where you allocate the -actual- node you're going to add to the list in InsertItem() and discovered you've commented out the allocation at line 151 of SortedType.cxx. There's your first problem.

Hopefully, this has not only solved your immediate issue, but given you some insight into how to debug your own programs! :)

raptr_dflo 48 Posting Pro

Probably the line in your code:

for(int i = 0; i < S[i].ImtiKieki() ; i++)

I think you meant for this line to specify "i < n". Happy coding!

raptr_dflo 48 Posting Pro

I would think you shouldn't declare your variables like you did[ float zero(float);].And why are you declaring them like variables when they are methods?
Ima newb programming only a year of experience but I've never seen it done like that.

Technically, they are functions. "Methods" are functions specifically bound to a class instance (or class itself, if declared as "static"). And the original poster is not "declaring them like variables", he's providing prototype declarations for the functions, which are then implemented farther down in the code.

The previous responder provided the first steps however: the prototype declaration must match the implementation, e.g.

int zero(float[9][13]);
raptr_dflo 48 Posting Pro

Third hit on a google search for your undeclared identifier provides a substantial sample code. Right at the top of it:

#define INITGUID
//#define D3D_OVERLOADS //might need to "unremark" this line, depending on if you use the overloads
#include <windows.h>
#include <stdio.h>
#include <ddraw.h>
#include <d3d.h>

The differences are: including d3d.h instead of d3d9.h, and defining INITGUID before including it. Do either of these resolve your problem?

raptr_dflo 48 Posting Pro

The glTranslate in your Draw() command is in (x,y,z) that take into account your heading rotation, while the one out in your do-while loop does not. One of them is probably incorrect. If you leave them where they are, and just change the rotations, does your model stay centered in your view and twist around as you expect? If so, try moving the one in Redraw to before the glRotates. If not, try moving the new one inside Redraw before the glRotates.

The "right" answer can certainly be painstakenly worked out on paper, given the documentation for how the OpenGL commands work, but I find it actually faster to take a known model (like a simple 3-axis, 3-color ball & stick object) and use trial and error to get the operations into the proper order and in the right directions. Now that you can actually see your model, it should go quicker. If you can't tell why it's moving incorrectly, start over and change as few values as possible, to narrow down which operations might be inverted, or specified in the wrong order. If needed, comment out operations while you test other ones, then put them back in when you're ready. Good luck!

raptr_dflo 48 Posting Pro

In Mouse(int *x, int *y), temp isn't allocated. Replace lines 12-15 with:

POINT temp;
    GetCursorPos(&temp);
    *x=temp.x;
    *y=temp.y;

In fact, if you might want to collect only the x or y value, pass NULL for the other pointer and reimplement as:

OpenGLInstance &OpenGLInstance::Mouse(int *x, int *y)
{
    if (x==NULL && y==NULL)
        return *this;
    POINT temp;
    GetCursorPos(&temp);
    if (x)
        *x=temp.x;
    if (y)
        *y=temp.y;
    return *this;
}

As far as keyboard keys, I'm not sure, but try putting a debug-print in your WndProc WM_KEYDOWN event and make sure that the value you're getting corresponds to the one you're checking for. I wouldn't be surprised if 'a' is really returning 'A' or even 'w' or 'W' depending on when the dvorak translation happens. Also try bumping the angle-increment up to 5 or 10 degrees, temporarily, so you -know- when it happens. :)

raptr_dflo 48 Posting Pro

On translation/rotation: keep in mind that order-of-operations matters. I think yours will likely do as you expect, as long as it's acceptable that R/L and F/B movement is relative only to the heading (and not the pitch U/D or roll CW/CCW). Also, since the OpenGL camera looks along its own Z-axis, I think maybe you want pos.h to rotate around that, rather than the X-axis. (And since it looks like you intend pos.h=0 to indicate a compass-heading of north, pos.t should rotate around Y and pos.v around X, try changing only one of those values away from zero at a time until you're getting the behavior you expect. Also as you change more than one value, you may find that you need to do roll first, then pitch, then heading.

As far as your Move function, pos.h-90 is 180 degrees off from pos.h+90, so sin and cos of one are negatives of the other, and the entire else{} block is redundant. Instead, double-check that you're moving in the correct direction for obvious values of pos.h (like 0 and 90). Again, to test, set all values to zero except pos.h, then Move only F/B or only L/R and make sure you see what you expect! Also, since the camera is at (0, 0, 0) to begin with, make sure you start with a sensible z value to push the model out in front of the camera. Getting close now! :)

raptr_dflo 48 Posting Pro

Wow, I'm really running out of good ideas. When all else fails, debug-prints!

Next up, if you can run your executable from a command-prompt, put a couple of printf/cout lines inside your do-while loop to make sure it's actually looping at the expected rate. Feel free to drop your desired frame-rate to 1Hz or less, so you can see the print's ticking by ... and/or add a counter that you can print out so you can see how fast that's changing. I have the vague feeling that something in the functionality is blocking when you aren't expecting it to, but I'm not sure. If your loop is running, we can then try to figure out why the Escape key doesn't exit, and why it doesn't appear to be rendering anything to the window. If it -isn't- looping, we can start narrowing down where it's getting stuck.

raptr_dflo 48 Posting Pro

And have you sanity-checked your frame-rate maintaining Sleep() value, within GL.Update()? If you accidentally send it a negative number, that may well be automatically converted to an unexpectedly very-large positive number! :)

raptr_dflo 48 Posting Pro

Assuming the stray #endif at line 53 is a left-over typo.

Also, from earlier, does your do-while loop in main() now look something like the following?

do {
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    model.Draw();
    GL.Update();
} while (!GL.window.key[VK_ESCAPE]);
raptr_dflo 48 Posting Pro

Nothing. Best bet is to start with the html link to mesa3d.org, and go from there. It will likely get you to the same point anyway, but in a more obvious fashion. (I put the ftp link up first, then went and tracked down the website, which was more user-friendly. Anyway, grab v7.11 I guess, and follow whatever instructions you can find for installing it. Or v7.10.3 if you can do without the absolute latest-and-greatest features and want a version that may be more stable until they get a bug-fix release out for 7.11.)

raptr_dflo 48 Posting Pro

Sorry, looks like a threw a bogus URL into my previous link. Try here:
ftp://ftp.freedesktop.org/pub/mesa/

from the main mesa site at http://www.mesa3d.org/

raptr_dflo 48 Posting Pro

Should I try to see if I can update the version of OpenGL on my machine?

I guess that depends on your machine. If you're on a laptop or other graphics-minimal machine, then I'd say yes, try downloading the latest stable version of Mesa (software OpenGL implementation).

If you're on a desktop-style machine with a half-decent graphics card, then the problem is more likely that you're building against the wrong version of the OpenGL headers and libraries, and have to find the correct ones ... if you need updates or are reasonably sure they didn't get installed when the card was added, go to the manufacturer's website to look for up-to-date drivers and possibly OpenGL implementations too.

raptr_dflo 48 Posting Pro

Oh, and it looks like I'm way out-of-date (obviously I don't do any new OpenGL development on this box!) -- Mesa is at 7.10 as of January 2011....

raptr_dflo 48 Posting Pro

Grrr... well, when I get more time, I'll see if I can beat some better behavior out of some version of your code. I'm out of ideas for the moment, and headed away from my computer for a few hours too. More later!

raptr_dflo 48 Posting Pro

and for your system()-call example, try something like this:

string cmd;
cout << "What command would you like to run?" << endl;
cin >> cmd;

cout << "Trying to run: system(\"" << cmd << "\")" << endl;
system(cmd.c_str());
raptr_dflo 48 Posting Pro

For what it's worth, I'm set up to use the MinGW gcc compiler, and the top of my gl.h file reads:

/*
 * Mesa 3-D graphics library
 * Version:  4.0
 *
 * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
...
raptr_dflo 48 Posting Pro

I'm getting a NULL-ptr returned from glGetString() also, and glGetError() returns x502 (INVALID_OPERATION) ... still looking into that.

As far as the texture coordinate thing, my typo sorry. That should have read:

glTexCoordPointer(2, GL_FLOAT, sizeof(glVertexStructure), &(vars[0].text[0]));
...
glNormalPointer(GL_FLOAT, sizeof(glVertexStructure), &(vars[0].norm[0]));
raptr_dflo 48 Posting Pro

I'm looking at section "23.070 How can I call extension routines on Microsoft Windows?" of the OpenGL FAQ. It looks like what you're already doing, but if you're getting undefined symbols with GOODGL defined, then those functions are presumably not in your opengl32.lib, and if you're getting NULL pointers back from wglGetProcAddress(), then they're not defined in your device's ICD either ... which indicates that your graphics hardware doesn't support the glGenBuffers() call -- also from the OpenGL website,

Notes: glGenBuffers is available only if the GL version is 1.5 or greater.

Also see this to find out what version of OpenGL you're running, and the question immediately below it if you suspect you're seeing weird behavior (picking unaccelerated pixel formats).

raptr_dflo 48 Posting Pro

Should line 446 above read something more like:

double frametime = 1000.0/(double)window.fps;
if (deltatime < frametime)
    Sleep(frametime-deltatime);

You can ignore what I said previously about glSwapBuffers, GL.Update() clearly does that, but you still need to draw into the other buffer, so your do {} while (); loop needs to clear, draw and Update() each time.

While you haven't gotten that far yet (past Compile()), unless you got your glGenBuffersD (etc.) pointers to be non-null, you're going to run into potential problems in model.Draw() where you call

...
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(2,GL_FLOAT,sizeof(glVertexStructure),(void*)((char*)(NULL)+sizeof(float)*(&(vars[0].text[0])-&(vars[0].vert[0]))));
    ...

if you haven't already called GL.LoadTexture() and GL.SetTexture().

The safest thing to do is probably pass the texture file into a model.AttachTexture() method which calls GL.LoadTexture(), and have the model maintain its texid. Then you can use whether the texid is non-zero to decide whether to call GL.SetTexture() and provide tex-coords.

Also, I think the offset to the first texture coordinate is probably as simple as:

glTexCoordPointer(2, GL_FLOAT, sizeof(glVertexStructure), &(vars[0].vert[0]));

and similar for the first normal coordinate.

But we still gotta figure out why you can't Compile(). If the pointers are NULL, we have to go back to where you assign them in genfunc(). If they're NULL there, then there's something wrong with how you're looking them up.

raptr_dflo 48 Posting Pro

For the errors (lines 14-17 of your output above), try wrapping line 10 of your code, replacing:

#include <gl/glext.h>

with

extern "C" {
    #include <gl/glext.h>
}

We can deal with the warnings later, but I think the first one might relate to your constructor-from-filename: vars and numv don't get initialized at all if you fail to open the file. For the signed vs. unsigned cases, when you're looping over the vars, since numv is declared to be unsigned, declare i to match.

As far as your clear (not black) screen ... try setting your glClearColor to opaque:

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

Also, since I don't know what GL.Update() does, perhaps your do{} loop needs to do something like:

do {
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  model.Draw();
  GL.Update();
} while (!GL.window.key[VK_ESCAPE]);

and if you have double-buffering enabled (you requested it in your pfd variable, but I don't think you ever check on return whether you actually got it), you probably need a glSwapBuffers(); call somewhere as well.

raptr_dflo 48 Posting Pro

Haha, oops. die() doesn't write its argument into the file! Line 190 should read: WriteData( s ); , not WriteData( "%s" );. Then you might get something useful. Sorry I missed that before! :)

raptr_dflo 48 Posting Pro

I think the PDB messages are warnings (about not being able to find debug symbols should you wish to use the debugger to see where the problem is) -- see the second response here for more info.

Other than that, the only actual "error" is that your program exited with code -1, which is exactly what the die() function does. Do you now have a File1.txt file? What messages are in it?

raptr_dflo 48 Posting Pro

I'm not seeing anything obvious at this point. One question is, at line 38 of GL.Init() above, you initialize pfd to include ... PFD_TYPE_RGBA, bpp, ... , but you're passing 24 in for bpp. Did you mean either to pass in 32, or to specify PFD_TYPE_RGB? Or will ChoosePixelFormat() do the right thing for you?

Other than that, to ensure that GL.Init() is actually working (at least a little), try commenting out the model.Draw(); line, and you should get a running app with a blank black screen. If that works, I'm worried that your looked-up function addresses are still wacky. Try printing out those pointer addresses and see if they make some sense:

printf("glGenBuffersD ptr = %p\n", glGenBuffersD);

Or if your compiler doesn't support %p (and you're building a 32-bit application), try:

printf("glGenBuffersD ptr = 0x%08x\n", (unsigned long)glGenBuffersD);

Other thoughts:
Why are you creating a default quadricobject in GL.Init()?
Should you be enabling GL_TEXTURE_2D if you're not creating and applying a texture-map?

raptr_dflo 48 Posting Pro

Hmmm... I suspect the memory you're corrupting isn't where you think it is. Can you post your main() that you're testing this against also?

raptr_dflo 48 Posting Pro

Are you also going to remove the leading declarations in genfunc(), now in lines 45-48?

raptr_dflo 48 Posting Pro

Now that you're using instance members for your GL function pointers, remove lines 9-12.

In genfuncs() (lines 49-52), you're declaring local variables that mask your class members, so that when you get to Compile(), the function-ptr members are still uninitialized. Omit the leading type-names, e.g.:

glGenBuffersD = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");

You should probably also check, at the top of Draw(), that your model actually contains something (numv > 0). I'm not sure what the functions in Compile() will do if you pass 0 vertices and a NULL ptr.

Hopefully this will get you past the immediate problem with Compile()!

raptr_dflo 48 Posting Pro

Can you clarify "get no result"? Were you able to build the executable? If so, did you get any error messages when you ran it? If it doesn't print anything to the console (assuming you're running it in a console window), did it occur to you that it might be running correctly?

Start with main() (at line 45 of the first block of code. After it declares a couple of variables, what does it do next? Skip that for a moment, and what does it do next? How is that next thing implemented? Assuming the code actually runs, are you OK to proceed?

raptr_dflo 48 Posting Pro

I may be mistaken at any point here, so try one thing at a time and see what (if anything helps).

First, at lines 9-12, you can declare your global function-pointers here, but I don't think you can call wglGetProcAddress() (or any other function) in the global scope. I think you need to assign the pointers to NULL and then call wglGetProcAddress() maybe in your GL.Init() or even just in main():

#ifndef GOODGL
if (!glGenBuffersD)
    glGenBuffersD=(PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");
...
#endif

In your destructor in lines 47-54, if you always allocate vars as vars = new glVertexStructure[numv]; then you should always deallocate it via delete [] vars; whether numv is 1 or greater. delete vars; is intended to be used in conjunction with vars = new glVertexStructure;. It might work as-is, but your code is actually cleaner without worrying about the count. Of course, still don't try to delete if numv is 0 (or equivalently if vars is NULL), and don't forget to check whether numv > 0 before allocating in your copy-constructor, assignment-operator, etc.

In lines 111-127, are you really going to support a statement like model = "filename.ext";? If not, you don't need this assignment operator. If you keep it, initialize the 'model' member as well (you set it to zero in the previous method).

In operator+=() (lines 144-156), you don't make your temp[] array any bigger than vars is, and then you assign the new 'add' piece into the wrong array and don't check vars before deleting, so …

raptr_dflo 48 Posting Pro

In no particular order:

Do not re-declare your member variables inside your constructor (lines 25-30). By specifying the types again, you have instead created local variables which mask your instance-members, and your instance-members are still uninitialized.

With that fixed, your constructor will be correct, but a preferred format is to initialize the members in an initialization-list, as follows:

Bank::Bank():
    badInput(false), nextChar('\0'), currentNumber(0), sum(0),
    firstChar('\0'), lastChar('\0')
{
    // any additional logic, besides initializing members, can go here
    // otherwise, leave it empty: {}
}

You still need int main (int argc, char *argv[]) , that's the only way for command-line arguments to get into your program.

If you have a whole bunch of different command-line arguments, especially optional ones, the code can get big enough that you might want a separate bool handleArgs(int argc, char *argv, Args & a) function which populated the members of an Args struct (note that in C++ a struct is just a class where everything is public by default) as appropriate, and returns true if the arguments were all valid and all required arguments were present, or false otherwise. But for now, handling the command-line in main() is fine.

You were fine up through

char* inputFileName= new char;
 
inputFileName= strstr (argv[1],"=")+ 1;

(though as AncientDragon pointed out, the first line leaks a tiny amount of memory, instead consolidate to char *inputFileName = strstr(argv[1], "=") + 1; )

But then, call a method passing the filename:

if (!bank.ReadFile(inputFileName)) { …
raptr_dflo 48 Posting Pro

You are providing the filename via the command-line. You can open the file wherever you like, e.g. by passing the filename to a method.

As far as why it doesn't work, you say you can't read in the first character of the file, but there's nothing in the edited-down source you've posted to indicate where you're trying to do that. Let's start at the beginning, and see your declaration for you Bank class. Did you remember to include a default constructor method Bank() and a destructor method ~Bank()?

raptr_dflo 48 Posting Pro

Glad to hear it. Please mark the thread as "solved" for us. Thanks! :)

raptr_dflo 48 Posting Pro

Try putting the numbers 1-20 into your array first (in order), and then shuffling it. (Hint: start by picking a random element-index and swapping that element with the last element in the array, now you have only 19 more elements to deal with, etc.)

raptr_dflo 48 Posting Pro

And romanNumber is declared as int at line 17. Definitely not the case. :)

raptr_dflo 48 Posting Pro

Also, if you haven't discovered it yet, your conversion is broken starting at line 20. Take any starting number, say, 2937, and trace through that block of code by hand, and see what values it's going to get for the four index variables.

raptr_dflo 48 Posting Pro

I bow to Mike's expertise here. My notions of efficiency are based entirely on hearsay, and nearly as old as the first C++ compilers; so if he says exceptions are the way to go, then it may not be "The Truth"(tm), but it's likely a more informed and up-to-date opinion than my own. This old dog (referring to myself) can still learn a new trick or two. Thanks for the insight!

raptr_dflo 48 Posting Pro

At the risk of being blunt, your code (at least as posted) cannot possibly be correctly identifying widgets with the work "type" in the widgetName element, because you're checking the age element (converted to a string).

Other than that, because you're checking each element with the correct name (or will be, once you fix that bug), and then keeping track of the maximum age value, and the vector-index of the corresponding element, you -are- in effect "storing that widget's info for comparison". The element is already stored in the vector, and the index allows you to get back to it at any point. If you wish, you can more explicitly copy the Element of interest into a separate variable, and perform your comparisons against that, including when to replace it with a new Element, but remember to keep track of the case where you haven't yet found any valid element, and at the end of you loop, check whether any elements with "type" in the widgetName were found.

Which reminds me, if you keep the code more or less as-is, be sure to initialize both highest_age and highest_age_index to sensible values (maybe -1 for both). Especially for the index (currently default-initialized to zero), if you go through all the widgets in your vector and don't find any with "type" in the widgetName, at the end of the loop, you'll incorrectly believe that element zero had the maximum age (of zero), even though it was never considered as a …

raptr_dflo 48 Posting Pro

I'm sure there are plenty of educated opinions on how to perform arbitrary type-conversions. Mine is: exceptions and exception-handling are important where you have insufficient control over determining whether an operation will succeed, but using the tried-and-true method of returning a success/failure indication is preferred, simply because it is more efficient (exception handling takes place outside of the normal function-call (and other lexical scoping) stack. Of course, I was raised in the pre-OO dinosaur days, and my early training has stuck with me.

On the opposite side of the argument, exception-handling may be thought of as more elegant. A divide-by-zero error 8 function calls deep doesn't need to be error-handled through each intervening function, and you can code "in the positive" ... assuming that everything will work correctly which is mostly the case, rather than laboriously making every function responsible for verifying the validity of its inputs and checking the success/failure status of every function called from within it: the argument here is that easily 80% of the code in a non-trivial function can end up being error-checking, rather than actually accomplishing the intended task.

For your specific use-case, you can certainly check the success of the ">> convertTo" operation (but remember to return "true" rather than "convertTo"), but what happens if your From-type or To-type don't implement a stringstream & operator<<(...) or stringstream & operator>>(...), respectively? Then you still get an exception, and you haven't handled it!

Mike wrote up an excellent discussion in

raptr_dflo 48 Posting Pro

You already have a "double if statement":

...
    if (widgetFinder.find("type", 0) != string::npos){
        if (widgetTypes[i].age > highest_age){
            ...

You just need to make sure you assign the correct member of widgetTypes (widgetName, not age) to your widgetFinder string.

raptr_dflo 48 Posting Pro

I think the problem is that you've declared it as a member function. Make sure the function is written as Mike said, e.g.

Element operator + (int a, const Element& b)  // note: not "Element::operator +"
{
    Element return_val;
    // make return_val be the sum of a and b
    return return_val;
}

and declare the function to be a friend of your class:

class Element {
    public:
        ...
        friend Element operator + (int a, Element & b);
        ...
};

Do the same for all three versions of your operator+.