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
Standish
May 21, 2001

hexadecimal posted:

what is a good library for C++ that is preferably cross-platform and would allow me to make HTTP-Requests?
libcurl

Adbot
ADBOT LOVES YOU

Whilst farting I
Apr 25, 2006

I'm really confused about classes/permissions. I'm trying to write some functions for an iterator, including begin, but I don't see how the iterator class can access/return the front node with the way this is set up.

Here's SingleLL.h

code:
template <typename T>
class SingleLL
{
private:
    class Node
    {
    public:
        T       val;
        Node    *nextNode;
    };

    Node    *front, *back;
    int     length;

public:
    SingleLL();
    int size() const;

    class iterator
    {
    public:
        iterator operator++();
        bool operator!=(const iterator & it2) const;
        T & operator*();
        Node    *pointer;
    };

    iterator begin();
    iterator end();
}
And here's the relevant excerpt from SingleLL.cpp, where begin is to be written.

code:
template <typename T>
typename SingleLL<T>::iterator SingleLL<T>::begin()
{
}
If it passed a list, I'd understand, but all iterator has access to is val and nextNode, neither of which I can gather can be used to get front. Here's the rough idea of what I have so far, but I'm otherwise stumped as to the syntax of the return.

code:
template <typename T> 
typename SingleLL<T>::iterator SingleLL<T>::begin()
{
    typename SingleLL<T>::iterator beginItr;
    Node *frontNode = new Node;
    frontNode = front;
    // return beginItr (something);
}
I assume end would be similar, but I'm not sure just how similar.

Whilst farting I fucked around with this message at 22:22 on Dec 2, 2008

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Whilst farting I posted:

I'm really confused about classes/permissions. I'm trying to write some functions for an iterator, including begin, but I don't see how the iterator class can access/return the front node with the way this is set up.

I'm not sure what you're confused about???

code:
template <typename T> 
typename SingleLL<T>::iterator SingleLL<T>::begin()
{
    return iterator(front);
}

Jethro
Jun 1, 2000

I was raised on the dairy, Bitch!

Whilst farting I posted:

I'm really confused about classes/permissions. I'm trying to write some functions for an iterator, including begin, but I don't see how the iterator class can access/return the front node with the way this is set up.
Just to clarify what AD wrote, as you have written them right now, begin() and end() are in SingleLL, not iterator, so there's no problem at all accessing front and back.

Whilst farting I
Apr 25, 2006

Avenging Dentist posted:

I'm not sure what you're confused about???

code:
template <typename T> 
typename SingleLL<T>::iterator SingleLL<T>::begin()
{
    return iterator(front);
}

When I do that I get a really long error whenever I call it, but here's the most relevant part

quote:

68 C:\SingleLL.cpp no match for call to `(SingleLL<std::vector<std::string, std::allocator<std::string> > >::iterator) (SingleLL<std::vector<std::string, std::allocator<std::string> > >::Node*&)'

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Whilst farting I posted:

When I do that I get a really long error whenever I call it, but here's the most relevant part

That's probably because you didn't write a constructor to your iterator. Just take a Node* and copy it to pointer in the iterator object.

Whilst farting I
Apr 25, 2006

code:
template <typename T> 
typename SingleLL<T>::iterator SingleLL<T>::begin()
{
    typename SingleLL<T>::iterator beginItr;
    Node *frontNode = new Node;
    frontNode = front;
    // return beginItr (something);
}
Isn't that what I was doing here? All variations of this I try don't work. The error message makes it seem like I'm returning a node, but when I call it it expects an iterator to be returned.

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

Whilst farting I posted:

code:
template <typename T> 
typename SingleLL<T>::iterator SingleLL<T>::begin()
{
    typename SingleLL<T>::iterator beginItr;
    Node *frontNode = new Node;
    frontNode = front;
    // return beginItr (something);
}
Isn't that what I was doing here? All variations of this I try don't work. The error message makes it seem like I'm returning a node, but when I call it it expects an iterator to be returned.

This code has a memory leak (you allocate a new node for frontNode and then reassign the pointer without deleting the original node), and you don't give the Node pointer to the iterator.

Here is a minimal change to the function to make it work, but it is by no means the advised solution:
code:
template <typename T> 
typename SingleLL<T>::iterator SingleLL<T>::begin()
{
    iterator beginItr; // You don't need to specify SingleLL here because you're inside SingleLL, so it's assumed
    beginItr.pointer = front;
    return beginItr;
}
To eliminate confusion, here's what the code should look like: http://paste.ifies.org/175

Whilst farting I
Apr 25, 2006

:doh: I knew it had something to do with how it was being returned and totally missed the whole pointer thing.

I've been trying this on a few different compilers to try and pinpoint the problem and some have been picky about the declarations, but the most specific one worked across them all so I had been using that.

Thanks for clarifying this!

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Once you get this working, you may want to look into Boost's Iterator Facade. It's basically a template that makes it much, much easier to write conforming iterator implementations (i.e. to make sure it does all the obscure stuff that iterators are required to do).

That Turkey Story
Mar 30, 2003

Avenging Dentist posted:

Once you get this working, you may want to look into Boost's Iterator Facade. It's basically a template that makes it much, much easier to write conforming iterator implementations (i.e. to make sure it does all the obscure stuff that iterators are required to do).

Somewhat improperly placed are also the Iterator Helpers of Boost.Operators which may be a simpler option.

Dren
Jan 5, 2001

Pillbug
Whilst Farting, I just wanted to be clear, this is for a school project right? You're not writing production code doing this are you?

TheSleeper
Feb 20, 2003

Dren posted:

Whilst Farting, I just wanted to be clear, this is for a school project right? You're not writing production code doing this are you?

I really hope nobody is rolling their own linked list for production code. This looks like a pretty standard data structures class assignment.

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.
I have to implement an ActiveX container. Not a control - I have the control. A container.

Oh, God, shoot me now.

Question 1: Anyone know where to find good docs on doing this? I can't find anything reasonable anywhere.

Question 2: I found a "sample" on MSDN, here. But it's not the actual sample, it's just a description of the sample and how to use it. I don't seem to have this sample installed anywhere with my copy of Visual Studio. Anyone know where to download the actual code for this?

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


Here's one for you all, about C++ and callbacks. In the current implementation of my code, my CDataContainer class has a set of three ordinary C function pointers that are set on construction and used throughout the class. The problem with these is, it's been decided that these need to be able to point to member functions INSTEAD of static/global functions.

The solution I came up with first was interfaces, then I remembered that C++ doesn't have interfaces. It DOES, however, have multiple inheritance. So I figure I could fake interfacing by writing a class like this:
code:
class CCallbacks
{
public:
  void output(...)=0;
  void reject(...)=0;
  void finish(...)=0;
};
where all the ...s are replaced as appropriate. Then I tell my coworkers to have classes that need to use callbacks with CDataContainer inherit from CCallbacks publicly, in addition to whatever classes they already inherited from, like so:
code:
class CDataMonitor : public CLogger, public CCallbacks
{
  void output(...) {do something;}
  // ditto reject and finish
...
};
I know multiple inheritance is omgevil, but the only alternative I could think of is having classes use a static wrapper and passing objects along via void pointers which strikes me as even worse. Is this multiple inheritance a reasonable solution? Or is there a better one I could be working with as far as allowing callbacks to member functions?

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.

Ledneh posted:

I know multiple inheritance is omgevil
It isn't. It can be overused, because there's usually a better way of accomplishing the same thing, and there can be trouble when the base classes have data members. But, you've come up with the simplest way of doing MI. It's almost exactly what an interface is: A class with unimplemented virtual functions and no member variables.

Don't forget the virtuals:
code:
class CCallbacks
{
public:
  virtual void output(...)=0;
Whether it's the best way for you to implement callbacks is debatable. I'm going to preempt Avenging Dentist and point you toward Boost.Function and Boost.Bind, which can be combined to create member function callbacks without having to come up with your own interface and having everything inherit from it. But, your way may be easier in your situation, depending on how your project is already architectured.

That Turkey Story
Mar 30, 2003

Ledneh posted:

I know multiple inheritance is omgevil, but the only alternative I could think of is having classes use a static wrapper and passing objects along via void pointers which strikes me as even worse. Is this multiple inheritance a reasonable solution? Or is there a better one I could be working with as far as allowing callbacks to member functions?

If you just need member functions you can use member function pointers. If you need one single object to be able to work with function pointers, member function pointers, more general function objects, etc. you should consider using TR1's function template or Boost.Function.

That Turkey Story
Mar 30, 2003

Mustach posted:

I'm going to preempt Avenging Dentist and point you toward Boost.Function and Boost.Bind

You beat out both AD and me to a boost link, that deserves an award.

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


Thanks for the link to boost::function, but I'm getting the impression from the guys upstairs (I need to check) that there could be many different classes that need to be able to support these callbacks, and I won't know in advance what classes these are, at least not yet (security clearance! :argh: ). Even if I DID know in advance, the fact that there could be more than one class in need of calling back I think means I need to use this fake-interface. (edit: I could be wrong, since I know literally dick about what bind is capable of)

Thanks for the suggestions, I'll look into them some more after lunch. And yeah, I forgot the virtuals 'cause I'm sort of a dullard when I'm not actually in front of a machine with a compiler :shobon:

Ciaphas fucked around with this message at 21:00 on Dec 3, 2008

Vanadium
Jan 8, 2005

Man, I was going to post the boost link before all of you, but I figured the guy wanted something more java-ish. :(

BigRedDot
Mar 6, 2008

You say you currently use composition (your classes HAVE three C function pointers). Well, if you use boost::function, you will still be using composition. Any class that wants callbacks will simply HAVE boost function objects.

And the best part is boost function objects can transparently encapsulate whatever you want. C functions. Functors. Static member functions. Instance member functions. Any or all of the above in combination. Even better, with together with boost::bind you can employ partial function application on more general callables to wrap them with individual per-callback-state before you store them as callbacks, if you need to.

Guaranteed, boost is absolutely more flexible and more portable and more complete than any possible wheel you decide to re-invent on your own.

BigRedDot fucked around with this message at 00:32 on Dec 4, 2008

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh

BigRedDot posted:

Guaranteed, boost is absolutely more flexible and portable and co,plete than anything possible thing you roll yourself.

Especially since Boost.Bind and Boost.Function are both a part of TR1.

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


Okay, consider me sold well enough. I did some reading up, and frankly I missed the boat earlier on how bind and function interrelate. I see it a little better now.

Still gonna take some working out I think, though, mostly to make sure I'm not running up against the rest of the group's wishes.

Thanks!

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.

That Turkey Story posted:

You beat out both AD and me to a boost link, that deserves an award.
Only by a minute, though; don't feel too bad. :whatup:

king_kilr
May 25, 2007

MarsMattel posted:

How about making a series of tests which cover a range of problems of varying difficulty? Just say ten or so examples like, "can you find the error in this piece of code?"
code:
int* Person::getAge() {
  int value = m_age;
  return &value;
}
Hopefully if you do a good range of tests you can get a good idea of the person's ability. I did a test like this in an interview, seemed like a decent idea.

I think questions like that tend to be a bit too easy, for example I'm a freshman CS student and I immediately see the problem there :/

POKEMAN SAM
Jul 8, 2004

king_kilr posted:

I think questions like that tend to be a bit too easy, for example I'm a freshman CS student and I immediately see the problem there :/

You'd be surprised who shows up at interviews saying they can program.

Mikey-San
Nov 3, 2005

I'm Edith Head!

Ugg boots posted:

You'd be surprised who shows up at interviews saying they can program.

I've seen CS grads show up to interviews lacking the ability to describe what a hash table is and how it works.

Zombywuf
Mar 29, 2008

Mikey-San posted:

I've seen CS grads show up to interviews lacking the ability to describe what a hash table is and how it works.

I've seen interviewees with CS masters unable to write a for loop.

hexadecimal
Nov 23, 2008

by Fragmaster

Zombywuf posted:

I've seen interviewees with CS masters unable to write a for loop.

How can something like that be possible?

floWenoL
Oct 23, 2002

hexadecimal posted:

How can something like that be possible?

hexadecimal posted:

check out this #define I have found somewhere and have been using for a while. It makes iterating through STL containers a lot easier.

code:
#define FOREACH(_it,_l) for(__typeof((_l).begin()) _it=((_l).begin());(_it)!=(_l).end();(_it)++) 

Hmm...

Mikey-San
Nov 3, 2005

I'm Edith Head!
^^^ ahahaha

Zombywuf posted:

I've seen interviewees with CS masters unable to write a for loop.

CS degrees, now available in every box of Cracker Jack(r) popcorn snacks!

POKEMAN SAM
Jul 8, 2004

hexadecimal posted:

How can something like that be possible?

A lot of the time you don't need a Bachelor's in CS to pursue a Master's in CS, for example a lot of schools will let you hop right into a Master's in CS program with a Physics or Math degree. Though you might need to take classes to satisfy prerequisites for the classes in the graduate school, you'll probably avoid taking any introductory programming classes, and often the Graduate CS classes are weighted more toward theory than programming, so you might not do much (if any) programming in Graduate school.

PT6A
Jan 5, 2006

Public school teachers are callous dictators who won't lift a finger to stop children from peeing in my plane

king_kilr posted:

I think questions like that tend to be a bit too easy, for example I'm a freshman CS student and I immediately see the problem there :/

Same, but I've run into people in my 200-level software systems course who can't figure out the problem when they're trying to compile code with a mismatched parenthesis.

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


So regarding boost::bind and boost::function again. Take the following example I borrowed from another programming forum:

pre:
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>

class container
{
public:
	boost::function<void()> callback;
};

class foo
{
public:
	void doStuff() {std::cout << "Hello World!\n";}
};

int main()
{
	container c;
	foo f;

	c.callback = boost::bind(&foo::doStuff, &f);

	c.callback();
}
Take that bolded line. If I take the ampersand out of before foo::doStuff, the example seems to work exactly the same as if I left it in. But are there any side effects I should know about?

Vanadium
Jan 8, 2005

Does not compile on gcc without the ampersand.

That Turkey Story
Mar 30, 2003

Ledneh posted:

Take that bolded line. If I take the ampersand out of before foo::doStuff, the example seems to work exactly the same as if I left it in. But are there any side effects I should know about?

You always form member function pointers by doing &Type::member_function, otherwise your code is non-standard and will not compile on a compliant compiler. This is true even when in the scope of the class. With non-member functions you can leave off the & and still be standard.

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


Another case of CC screwing with me, then. :mad:

Ciaphas
Nov 20, 2005

> BEWARE, COWARD :ovr:


Okay, there's two different ways I can think of of going about this. Pretend when you read these that I bothered checking for null errors and such; my internet computer and compiler computer are not one and the same, or even near each other, so I'm kind of playing by ear.

This first way doesn't require the caller (read: the rest of the team) to use or even know about boost::bind or boost::function, which is good for them, but makes me have to use a void*, and looks a little odd to use.

my code
code:
class CDataContainer
{
public:
  void setCallback(boost::function<void(int)> func, void* obj);
  void callback(int param) { mCallback(param); }

private:
  boost::function<void(int)> mCallback;
};

// precond: obj points to an object of the class func is a member of
void CDataContainer::setCallback(boost::function<void(int)> func, void* obj)
{
  if (NULL == obj) // there's probably a better way to check if this is a member function pointer or not...
    mCallback = func;
  else
    mCallback = boost::bind(func, obj, _1);
}
their code that uses my code
code:
void globalFunc(int param) {}
static void CClass::staticMemberFunc(int param) {}
void CClass::memberFunc(int param) {} // pretend the class declaration is up there somewhere

void main()
{
  CClass cl; // CClass is some class of theirs that needs me to call them back
  CDataContainer cd;
  
  cd.setCallback(&CClass::memberFunc, &cl);
  cd.callback(12); // does whatever memberFunc does, acting on cl as *this

  cd.setCallback(&CClass::staticMemberFunc, NULL);
  cd.callback(24); // ditto staticMemberFunc, with no *this (obviously)

  cd.setCallback(&globalFunc, NULL);
  cd.callback(36); // ditto again for free function
}
The second is the same way, except I count on the rest of the team to use boost::bind where needed. Cleaner and less error-prone for me, and probably more type-safe, but the rest of the group has to learn how (and remember) to use boost::bind.

my code
code:
class CDataContainer
{
public:
  void setCallback(boost::function<void(int)> func);
  void callback(int param) { mCallback(param); }

private:
  boost::function<void(int)> mCallback;
};

void CDataContainer::setCallback(boost::function<void(int)> func)
{
  mCallback = func;
}
their code
code:
void globalFunc(int param) {}
static void CClass::staticMemberFunc(int param) {}
void CClass::memberFunc(int param) {} // pretend the class declaration is up there somewhere

void main()
{
  CClass cl; // CClass is some class of theirs that needs me to call them back
  CDataContainer cd;
  
  cd.setCallback(boost::bind(&CClass::memberFunc, &cl, _1));
  cd.callback(12); // does whatever memberFunc does, acting on cl as *this

  cd.setCallback(&CClass::staticMemberFunc);
  cd.callback(24); // ditto staticMemberFunc, with no *this (obviously)

  cd.setCallback(&globalFunc);
  cd.callback(36); // ditto again for free function
}
I'm leaning toward the second way right now, but I thought I'd run it by you all, since you're all a load smarter than I am with this stuff and there's probably an option I missed. What say you?

(ed) Also, thanks for your patience with me, I know these are sort of basic questions but I'm new to the practical world of programming. The theoretical world of college programming was easier :(

Ciaphas fucked around with this message at 19:35 on Dec 4, 2008

newsomnuke
Feb 25, 2007

Take this function:
code:
template <typename T>
T sumArray (const vector<T> &arr)
{
	T sum = 0;
	for (size_t i = 0; i < arr.size (); ++i)
		sum += arr[i];

	return sum;
}
How would I generalise it for types which do not use 0 as their base/empty value: for example, strings or complex numbers?

Adbot
ADBOT LOVES YOU

Vanadium
Jan 8, 2005

T sum = T(); should work in all cases I can think of.

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