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
Lexical Unit
Sep 16, 2003

Vanadium posted:

http://library.gnome.org/devel/gobject/unstable/index.html seems to be a pretty good place to start with gobject.


Right, that's from the same documentation as the link in my first post. I was looking for something more along the lines of "Creating you're own custom GTK widgets" as opposed to "Understanding the nitty-gritty details of GObject, which by the way happens to be what GTK is based on, but let's not saying anything about GTK here. We'll leave that as an exercise for the reader."

Adbot
ADBOT LOVES YOU

Avenging Dentist
Oct 1, 2005

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

Avenging Dentist posted:

I definitely want to do the latter, but it gets a little bit hairy, since, in order to pass an associative container class template as a template argument, I'd need to know the exact number of template parameters it uses.

Actually, it looks like GCC 4.4 handles this via N2555!

That Turkey Story
Mar 30, 2003

Avenging Dentist posted:

Yeah, I switched to using the tuple constructor. I'm not sure if it's dictated by the standard, but GCC's implementation of TR1 allows me to create a tuple of rvalue-refs and then pass that into the std::map, even though the map expects a tuple of value-types. I'd have to test it with a "noisy" class to make sure it minimizes copying, but it seems like it'd work.
I don't know how it is specified, but my gut is it's just working because the conversion is taking place during the argument passing to find and operator[]. You probably want to do the conversion externally to the key type before-hand to prevent the conversion from occurring multiple times.

Avenging Dentist posted:

I think you mean rvalue refs
Yeah, my mistake.

Avenging Dentist posted:

The former should be pretty trivial, since I should just be able to drop tr1::function in there.
Rather than that, you'd probably want to allow them to override the function type via the template argument (if it's a function type, convert it to a function pointer to use internally, otherwise treat the type as a function object type and just use that internally). You don't really need the polymorphism provided by tr1::function so you probably shouldn't make it a necessary part of the template -- the user can potentially get more optimized results by using functors. As well, this way, if a user does need a tr1::function, they can always specify it like any other function object type, but those who don't need it don't pay for the cost.

Avenging Dentist posted:

I definitely want to do the latter, but it gets a little bit hairy, since, in order to pass an associative container class template as a template argument, I'd need to know the exact number of template parameters it uses. Maybe concepts would help with that if they ever got pushed into GCC main (or the Standard, for that matter).
Pass an MPL-style metafunction class -- a type with a nested metafunction (apply). This gets around having to use template template parameters and knowing how many template parameters there are.

Avenging Dentist posted:

The updated version of all this malarkey is here: http://pastebin.com/f251786c4
operator () should probably be a variadic template of rvalue refs, or non-ref parameters corresponding to the passed in parameter types as you had it before (though preferably the former), but not rvalue refs of the specified parameter types as you have it now since you will just bind to both lvalues and rvalues and lose the information about whether it was an lvalue or rvalue to begin with (and it won't handle other types). You should be forwarding like you would in other situations. Use std::forward when passing arguments to the tuple constructor (the tuple would be of the argument types passed to the class template, not the function template, with no rvalue ref added, it should be the same as the key type). This makes it so conversion happens only once and there will be just 1 tuple copy operation (internal to the operator[] call).

Edit:

Avenging Dentist posted:

Actually, it looks like GCC 4.4 handles this via N2555!

Never even saw this!

That Turkey Story fucked around with this message at 00:01 on Jan 6, 2009

Avenging Dentist
Oct 1, 2005

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

That Turkey Story posted:

I don't know how it is specified, but my gut is it's just working because the conversion is taking place during the argument passing to find and operator[]. You probably want to do the conversion externally to the key type before-hand to prevent the conversion from occurring multiple times.

Yeah, that's the case.

That Turkey Story posted:

Rather than that, you'd probably want to allow them to override the function type via the template argument (if it's a function type, convert it to a function pointer to use internally, otherwise treat the type as a function object type and just use that internally).

I'll probably mess with this a bit. It may even be possible to pass in a function as a template parameter to take advantage of inlining.

That Turkey Story posted:

Stuff about forwarding

Right now, I'm just working on getting it to make fewer copies in general, before I worry about move semantics. Annoyingly, both GCC and MSVC seem to invoke 2 copy operations whenever you use the my_map[i] syntax.

That Turkey Story
Mar 30, 2003

Avenging Dentist posted:

I'll probably mess with this a bit. It may even be possible to pass in a function as a template parameter to take advantage of inlining.
You should be able to support that implicitly through support for arbitrary function objects, assuming the following definition (untested, probably mistakes):

code:
template< typename FunType, FunType Fun >
struct inline_function
  requires std::True< std::is_function< FunType >::value >
{
  template< typename... Params >
    requires std::Callable< FunType*, Params... >
  auto operator ()( Params&&... args ) const -> decltype( Fun( std::forward< Params >( args )... ) )
  {
    return Fun( std::forward< Params >( args )... );
  }
};
You can then use it without requiring any special code in the memoizer assuming you already provide support for function objects.

Avenging Dentist posted:

Right now, I'm just working on getting it to make fewer copies in general, before I worry about move semantics. Annoyingly, both GCC and MSVC seem to invoke 2 copy operations whenever you use the my_map[i] syntax.

What's your code? It's probably because you are passing a type different from the key type, meaning a convert during argument passing and then a copy when storing it in the map.

Edit: In other words because you did this in your posted code:

code:
std::tr1::tuple<Args &&...>
but the key type is:

code:
std::tr1::tuple<Args...>
meaning that when you call operator[], the former is converted to the latter when passing it to the function, and then the tuple is also copied into the map's internal storage.

That Turkey Story fucked around with this message at 02:05 on Jan 6, 2009

Avenging Dentist
Oct 1, 2005

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

That Turkey Story posted:

What's your code? It's probably because you are passing a type different from the key type, meaning a convert during argument passing and then a copy when storing it in the map.

Edit: In other words because you did this in your posted code:

code:
std::tr1::tuple<Args &&...>
but the key type is:

code:
std::tr1::tuple<Args...>
meaning that when you call operator[], the former is converted to the latter when passing it to the function, and then the tuple is also copied into the map's internal storage.

Actually, there aren't any conversions, and it appears that operator[] creates an std::pair and passes it to insert. It also seems that tr1::tuple doesn't support move semantics, since I'm pretty sure I'm forwarding properly.

Here's the code anyway. I also changed it so that the tuple doesn't store references if the function takes a reference.

Oh, also my code is dangerous right now since it potentially moves an object and then uses the original object in the call to fcn_.

EDIT: Ok, I wrote my own tuple class with move semantics, and I can confirm that the GCC TR1 implementation of tuple does not support move semantics. Based on N1403, there doesn't appear to be anything about move semantics in there, but that paper is pretty old, and I'm not sure if it's been superseded.

EDITx2: Ahhh, I want <tuple> for the 0x code, not <tr1/tuple>.

Avenging Dentist fucked around with this message at 07:48 on Jan 6, 2009

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
Alright, be warned: this code is absolutely loving awful and uses a bunch of pointer hacks, but I managed to cut down the number of copies to just one when the map doesn't have the memoized value stored: http://pastebin.com/f1c82b332

EDIT: Updated

Avenging Dentist fucked around with this message at 08:29 on Jan 6, 2009

Cosmopolitan
Apr 20, 2007

Rard sele this wai -->
Just a small question:

What's the real difference between "\n" and "endl"? My teacher recommended we use \n because you are more likely to avoid problems with it on other platforms, such as a Unix environment. I think I read somewhere that the only difference between the two was that "endl" flushes the I/O buffer, or something to that effect.

That Turkey Story
Mar 30, 2003

Yes, endl just flushes in addition to the new line.

hexadecimal
Nov 23, 2008

by Fragmaster

That Turkey Story posted:

Yes, endl just flushes in addition to the new line.

Is endl OS specific or does it only add '\n' not "\r\n" on Windows in addition to flushing?

That Turkey Story
Mar 30, 2003

hexadecimal posted:

Is endl OS specific or does it only add '\n' not "\r\n" on Windows in addition to flushing?

Outputting '\n' should do appropriate formatting (same with endl).

csammis
Aug 26, 2003

Mental Institution

hexadecimal posted:

Is endl OS specific or does it only add '\n' not "\r\n" on Windows in addition to flushing?

In text mode output streams on Win32, \n is automatically expanded to \r\n :eng101:

opie
Nov 28, 2000
Check out my TFLC Excuse Log!
I am stupid and know almost nothing about using COM and ActiveX. Now I need to add some C++ code to our system that will call a third party's ActiveX methods, but all they sent was a document of the method names and a utility that vaguely has to do with the interface but contains no header files or the OCX file named in the documentation. I assume I need those and the utility files are of no use for this task (exes and dlls).

This other company likes to forget about conference calls that they schedule with us, and wait several weeks to send requested documentation, so I wouldn't put it past them to knowingly not send what I need. But since I'm new at this stuff, I don't want to look like a dumbass and ask for stuff I don't need. I mean I am a dumbass, but they don't need to know that.

Edit in case the question wasn't clear - what do I need from a third party to call their ActiveX methods?

opie fucked around with this message at 18:33 on Jan 8, 2009

ehnus
Apr 16, 2003

Now you're thinking with portals!

csammis posted:

In text mode output streams on Win32, \n is automatically expanded to \r\n :eng101:

This should probably go into the coding horrors thread because the automatic new line conversion makes it impossible to pipe binary data between processes.

Le sigh.

TSDK
Nov 24, 2003

I got a wooden uploading this one

ehnus posted:

This should probably go into the coding horrors thread because the automatic new line conversion makes it impossible to pipe binary data between processes.

Le sigh.
If you open the stream in binary mode, then '\n's go through unmolested.

honeymustard
Dec 19, 2008

Shut up cunt.
I've just started dabbling in C++ for a course I am on, and I'm having some trouble with this matrix. I just need a 3x3 matrix, filled in with 1-9, so I am using this function to initialise it:

code:
void initialisematrix(void)
{
	int a, b, c;
	for(c=0; c<10; c++) {
		for(a=0; a<3; a++) {
			for(b=0; b<3; b++) {
				matrix[a][b] = c;
			}
		}
	}
}
Problem is, it seems to fill in every position with 9, rather than incrementing it. Is there an easier way of doing it that I'm missing?

Edit: another way I'm trying is:

code:
void initialisematrix(void)
{
	int a, b, c;
	c = 1;
		for(a=0; a<3; a++) {
			for(b=0; b<3; b++) {
				matrix[a][b] = c;
				c = c + 1;
		}
	}
}
Though this gives me: 1, 3, 4, 4, 6, 7, 7, 9.

honeymustard fucked around with this message at 19:05 on Jan 8, 2009

whoknew
Sep 18, 2004


oh shit
im lit



honeymustard posted:

I've just started dabbling in C++ for a course I am on, and I'm having some trouble with this matrix. I just need a 3x3 matrix, filled in with 1-9, so I am using this function to initialise it:

code:
void initialisematrix(void)
{
	int a, b, c;
	for(c=0; c<10; c++) {
		for(a=0; a<3; a++) {
			for(b=0; b<3; b++) {
				matrix[a][b] = c;
			}
		}
	}
}
Problem is, it seems to fill in every position with 9, rather than incrementing it. Is there an easier way of doing it that I'm missing?

You've got the loop that controls the value you assign as the outermost one, so you're actually writing the entire array 10 times. It just so happens that the last time around it writes 9 to every index.

TSDK
Nov 24, 2003

I got a wooden uploading this one

honeymustard posted:

Problem is, it seems to fill in every position with 9, rather than incrementing it. Is there an easier way of doing it that I'm missing?
Yes, but first you need to re-read your code and understand what you've written.

Add in a few prints and see if you can follow the logic:
code:
void initialisematrix(void)
{
	int a, b, c;
	for(c=0; c<10; c++) {
		for(a=0; a<3; a++) {
			for(b=0; b<3; b++) {
				printf( "Setting matrix[%d][%d] to %d\n", a, b, c );
				matrix[a][b] = c;
			}
		}
	}
}

hexadecimal
Nov 23, 2008

by Fragmaster
The problem is in your loop logic. You don't need the outer loop for c.

code:
int c = 1;
for( int i = 0; i < 3; ++i )
{
    for( int j = 0; j < 3; ++j )
    {
       matrix[i][j] = c;
       c++;
    }
}

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

honeymustard posted:

Problem is, it seems to fill in every position with 9, rather than incrementing it. Is there an easier way of doing it that I'm missing?

The "clever" way; deriving the data from the indices.

code:
for( int i = 0; i < 3; ++i ) {
  for( int j = 0; j < 3; ++j ) {
    matrix[i][j] = 3 * i + j + 1;
  };
};
The "naive" way; using an explicit accumulator.

code:
int n = 1;
for( int i = 0; i < 3; ++i ) {
  for( int j = 0; j < 3; ++j ) {
    matrix[i][j] = n;
    ++n;
  };
};

honeymustard
Dec 19, 2008

Shut up cunt.
Wow, thanks for all the replies, haha. whoknew, TSDK: I see now, the print makes it clear what's happening - thanks.

Edit: I also had a mistake in the print function, which made it unclear what was going on, so adding the print inside the loop was very helpful indeed. Thanks again :)

honeymustard fucked around with this message at 19:13 on Jan 8, 2009

hexadecimal
Nov 23, 2008

by Fragmaster

ShoulderDaemon posted:

The "naive" way; using an explicit accumulator.

code:
int n = 1;
for( int i = 0; i < 3; ++i ) {
  for( int j = 0; j < 3; ++j ) {
    matrix[i][j] = n;
    ++n;
  };
};

Why do you have ; after }

Is it any different than from omitting it?

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

hexadecimal posted:

Why do you have ; after }

Is it any different than from omitting it?

No, it's just habit from other languages which require it.

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

ShoulderDaemon posted:

No, it's just habit from other languages which require it.
Speaking personally, spending a semester writing a Pascal compiler gets you into positively bizzare syntax habits. It got to the point where I started doing this, myself :)

Null Pointer
May 20, 2004

Oh no!

hexadecimal posted:

Why do you have ; after }

Is it any different than from omitting it?
It's just an empty expression statement. It does nothing as long as it's used where a statement is expected.

Cosmopolitan
Apr 20, 2007

Rard sele this wai -->

That Turkey Story posted:

Yes, endl just flushes in addition to the new line.
So does it really matter which one you use?

ShoulderDaemon posted:

The "clever" way; deriving the data from the indices.

code:
for( int i = 0; i < 3; ++i ) {
  for( int j = 0; j < 3; ++j ) {
    matrix[i][j] = 3 * i + j + 1;
  };
};

Oh, that's weird, so C++ does all calculations linearly if you don't specify otherwise (with parenthises or whatever)? I first looked at that and thought it would do it like "3(i+j+1)".

Also, how would I make an array's dimension size dependent upon the user input? Like if I entered 4, it would make the array in question 4-dimensional.

hexadecimal
Nov 23, 2008

by Fragmaster

Anunnaki posted:

So does it really matter which one you use?


Oh, that's weird, so C++ does all calculations linearly if you don't specify otherwise (with parenthises or whatever)? I first looked at that and thought it would do it like "3(i+j+1)".

Also, how would I make an array's dimension size dependent upon the user input? Like if I entered 4, it would make the array in question 4-dimensional.

I am pretty sure C++ and any other serious languages do operator precedence. So if you have a + b + c * d it is not going to be (a+b+c)*d, but the correct way you'd expect it to be, i.e. a + b + (c*d)

For your second question, the easiest way is to use a one dimensional array but come up with a mapping formula, so you can treat it as n-dimensional array.

Easiest example is how to represent a 2d array using 1d array. if i and j are coordinates of 2d array then in 1d array they would map to new index n = (j*size_in_i)+i

hexadecimal fucked around with this message at 23:05 on Jan 8, 2009

Mata
Dec 23, 2003

Anunnaki posted:

I first looked at that and thought it would do it like "3(i+j+1)".
Why would you think that?

TheSleeper
Feb 20, 2003

Anunnaki posted:

So does it really matter which one you use?


Oh, that's weird, so C++ does all calculations linearly if you don't specify otherwise (with parenthises or whatever)? I first looked at that and thought it would do it like "3(i+j+1)"

Uh, C++ follows the proper mathematical order of operations. If somebody told you x = 3 * 2 + 1 + 2, would you say that x is 9 or 15? Obviously 9. Why would C++ do it any other way?

TheSleeper fucked around with this message at 23:05 on Jan 8, 2009

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

TheSleeper posted:

Uh, C++ follows the proper order of operations. If somebody told you x = 3 * 2 + 1 + 2, would you say that x is 9 or 15? Obviously 9. Why would C++ do it any other way?
To make it easier for compiler writers :downs:

Avenging Dentist
Oct 1, 2005

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

Dijkstracula posted:

To make it easier for compiler writers :downs:

Welcome to the wild and wooly world of MUMPS! :D

Null Pointer
May 20, 2004

Oh no!

Dijkstracula posted:

To make it easier for compiler writers :downs:
C++ has 18 levels of precedence if you include sequential evaluation. I don't really see much of a point. You could hypothetically replace 5 of these levels with a single strict left-associative infix expression and maybe even pick up custom operators at the same time.

It's all baggage from C anyway, so this ship sailed a long time ago.

Cosmopolitan
Apr 20, 2007

Rard sele this wai -->

TheSleeper posted:

Uh, C++ follows the proper mathematical order of operations. If somebody told you x = 3 * 2 + 1 + 2, would you say that x is 9 or 15? Obviously 9. Why would C++ do it any other way?

Oh, wait, never mind, I was thinking of something like x = 3 * 2 + 1 + 4 * 5, in which you'd do the multiplications first. Never mind I said anything. Brain fart. :byodood:

Edit: VVVVVVVVV
Is that not what I said? :raise:

Cosmopolitan fucked around with this message at 01:49 on Jan 9, 2009

TheSleeper
Feb 20, 2003

Anunnaki posted:

Oh, wait, never mind, I was thinking of something like x = 3 * 2 + 1 + 4 * 5, in which you'd do the multiplications first. Never mind I said anything. Brain fart. :byodood:

I think your brain is still farting, because you ALWAYS do multiplication before addition when parentheses do not indicate otherwise.

Always.

UberJumper
May 20, 2007
woop

Avenging Dentist posted:

Alright, be warned: this code is absolutely loving awful and uses a bunch of pointer hacks, but I managed to cut down the number of copies to just one when the map doesn't have the memoized value stored: http://pastebin.com/f1c82b332

EDIT: Updated

What... is it?

Avenging Dentist
Oct 1, 2005

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

UberJumper posted:

What... is it?

It memoizes the results of a function.

honeymustard
Dec 19, 2008

Shut up cunt.
To follow up on my previous post...

What I'm trying to do is a simple tic tac toe game with one player and computer (which generates a random position), using a 3x3 matrix (which is filled with 1-9, so the player or computer picks one of those numbers). It's pretty much finished now, except I'm trying to add some validation, so the player or computer cannot choose a position that is already occupied from a previous turn. I just can't figure out how to implement this though... the code I'm using for the computer's turn is:

code:
void computerturn(void)
{
	// Generate a random number between 1 and 9
	srand((unsigned)time(0)); 
        int cpumove;
	cpumove = (rand()%9)+1;
	char cpumovechar;
	// Convert the integer generated into a char
	cpumovechar = cpumove + '0';

	int a, b;
	
	// Loop a = 0, 1, 2
	for(a=0; a<3; a++) {
		// Loop b = 0, 1, 2
		for(b=0; b<3; b++) {
			// Check if the contents of the position of the matrix match computer's move
			if (matrix[a][b] == cpumovechar)
				// If they do, stick an O in there, otherwise, loop to next position
				matrix[a][b] = 'O';
		}
	}

	cout << "Computer chooses position " << cpumovechar << ".\n";

}
Does anyone have any ideas how I could add in the validation? Thanks.

hexadecimal
Nov 23, 2008

by Fragmaster
Use constant characters for player and computer. In your matrix put 'c' for computer having a piece there and 'p' for player having a piece there. Use some other character or 0 to represent empty square. You really don't have to use characters, you can just use an integer to represent computer and player. Just make sure that player is always represented by same number/character, and so is computer.

To generate a random move, generate 2 random numbers in range 0<=n<3. Check if the random coordinate you generated is occupied or not, and repeat until you hit unoccupied one. That is probably the easiest way. However, you can use a queue. Generate all 9 coordinates, then put them in random position in linked list. Then just read the first one in that linked list to get your random coordinate, then remove it, and so on. This way you wouldn't be doing needless loop cycles.

code:
#include <list>
#include <stdlib.h>
... 
list<pair<int,int> > gen_coor_queue( )
{
     list<pair<int,int> > ret;
     for( int i = 0; i < 3; ++i )
     {
          for( int j = 0; j < 3; ++j )
          {
               pair<int,int> new_pair( i, j );
               int rand_choice = rand()%1;
               if( rand_choice == 0 ) ret.push_back( new_pair );
               else ret.push_front( new_pair );
          }
     }
     return ret;
}
This will give you a semi random list.

hexadecimal fucked around with this message at 19:28 on Jan 9, 2009

honeymustard
Dec 19, 2008

Shut up cunt.
Well the thing is, in the specification, it says we have to have 1-9 in the matrix, and then X and O for the pieces.

Edit: didn't see the edited stuff you added, I'll give that a try. Cheers

Adbot
ADBOT LOVES YOU

hexadecimal
Nov 23, 2008

by Fragmaster

honeymustard posted:

Well the thing is, in the specification, it says we have to have 1-9 in the matrix, and then X and O for the pieces.

Edit: didn't see the edited stuff you added, I'll give that a try. Cheers

Do you have to print it out using X or O or use such char in your matrix? If its just for printing out, then you can really use whatever you want for your actual matrix.

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