Error when returning a Pair from a function

Started by
9 comments, last by MarcusAseth 6 years, 6 months ago

Maybe today I'm confused and I'm missing the obvious...

I've made this simple struct inside my Utility.h 


template<typename TFirst, typename TSecond>
	struct Pair {
		Pair(TFirst f, TSecond s):First{f},Second{s}{}
		TFirst First;
		TSecond Second;
	};

And I'm using it from App.h (which #include "Utility.h") like so:

App.h


Pair<Uint32, Uint32> GetWindowSize();

App.cpp


Pair<Uint32, Uint32> App::GetWindowSize()
{
	return Pair<Uint32, Uint32>(Width,Height);
}

And I'm getting a cascade of errors ALL on line 39 (image below).

Any idea what I am doing wrong this time? x_x

eyvZQu7.png

 

EDIT: please mod delete this topic, I just remembered Utility.h put everything inside namespace util, sorry x_x

Advertisement

Why not use std::pair, which is significantly more full-featured and optimal?

Why are you using a pair to return a window size? A size is a conceptually richer concept, which includes a different set of operations and relationships than the more-generic "pair" concept. This seems like a prematurely-pessimized API design.

I didn't wanted to have to add another include in all my files in order to use that, since I already had my Utility.h included I put my class inside of that. There is a way to add the std::pair to my Utility.h so that all files including it get to use std::pair without including anything else?

Quote

A size is a conceptually richer concept, which includes a different set of operations and relationships than the more-generic "pair" concept

I don't fully understand this, I basically just needed to pass around width and height so that I can spawn my Entities like so(code below:

EDIT: by the way, why the code below is being pasted in this crazy way?!  Maybe a problem in how the tab character is interpreted?

It should appear like this --> https://pastebin.com/iddWWWfH


GameMode::GameMode(SDL_Window* Window, SDL_Renderer* Renderer, App* App)
	:Window{ Window }, Renderer{ Renderer }, AppRef{ App }, Running{ true }
{
	float WindowWidth = static_cast<float>(AppRef->GetWindowSize().First);
	float WindowHeight = static_cast<float>(AppRef->GetWindowSize().Second);
	
	//PhysicsManager
	PhysicsManager = std::make_unique<Physics>(this);

	//Create Player
	Entities.push_back(std::make_unique<Paddle>(this,
												static_cast<int>(WindowWidth) / 2,
												static_cast<int>(WindowHeight) - 40,
												PivotMode::CENTER));

	//Boundaries
	//Right
	Entities.push_back(std::make_unique<Boundary>(this,
												  Rect{ WindowWidth - 5.f, 0.f,
													   50.f, WindowHeight },
												  PivotMode::CENTER));
	//Left
	Entities.push_back(std::make_unique<Boundary>(this,
												  Rect{ -45.f, 0.f,
												  50.f, WindowHeight },
												  PivotMode::CENTER));
	//Top
	Entities.push_back(std::make_unique<Boundary>(this,
												  Rect{ 6.f, -45.f,
												  WindowWidth - 12.f, 50.f },
												  PivotMode::CENTER));

	//Bottom
	Entities.push_back(std::make_unique<Boundary>(this,
												  Rect{ 6.f, WindowHeight - 5.f,
												  WindowWidth - 12.f, 50.f },
												  PivotMode::CENTER));

	//Create Ball
	Entities.push_back(std::make_unique<Ball>(this,
											  static_cast<int>(WindowWidth) / 2,
											  200,
											  PivotMode::CENTER));
}

 

11 minutes ago, MarcusAseth said:

EDIT: by the way, why the code below is being pasted in this crazy way?!  Maybe a problem in how the tab character is interpreted?

It is, a TAB character is defined to aligned at multiples of 8 characters, in ASCII. Most editors ignore this definition, and allow you to change it, giving the illusion that a TAB is whatever you configured. That of course fails as soon as your file leaves your editor, since other programs or other people use different TAB settings, or use the official size.

2 minutes ago, Alberth said:

It is, a TAB character is defined to aligned at multiples of 8 characters, in ASCII. Most editors ignore this definition, and allow you to change it, giving the illusion that a TAB is whatever you configured. That of course fails as soon as your file leaves your editor, since other programs or other people use different TAB settings, or use the official size.

though this pastes correctly on codeshare.io and pastebin and Windows blocknote and pretty much everywhere else... wouldn't be better to have the site behaving the same way? :P

Just now, MarcusAseth said:

though this pastes correctly on codeshare.io and pastebin and Windows blocknote

It can't paste correctly in all cases. TAB length isn't copied with the text, so either it guestimates, or it just happens to use the same length as you have. In both cases, you can break the formatting with a clever enough example.

 

24 minutes ago, MarcusAseth said:
Quote

A size is a conceptually richer concept, which includes a different set of operations and relationships than the more-generic "pair" concept

I don't fully understand this, I basically just needed to pass around width and height so that I can spawn my Entities like so(code below:

This means that if two numbers have a width and height relation, you can discuss other properties, eg "area". You can multiply 2 unrelated numbers, with each other, but without a width/height relation between them it has no useful meaning.

58 minutes ago, MarcusAseth said:

I didn't wanted to have to add another include in all my files in order to use that, since I already had my Utility.h included I put my class inside of that. There is a way to add the std::pair to my Utility.h so that all files including it get to use std::pair without including anything else?

No, but including <utility> isn't going to be a huge deal, especially if you're just taking your Utility.h and turning into a convenience catch-all anyway. The net impact on compile time over the life of any nontrivial project will probably be smaller using <utility>, since it changes so infrequently, whereas your Utility.h will change quite often.

1 hour ago, MarcusAseth said:

I don't fully understand this, I basically just needed to pass around width and height so that I can spawn my Entities like so(code below:

Why do you have a Window class then? Why not Tuple<std::string, int, int, Pair<int, int>, bool, bool, ...>? It's the same thing, right?

Seeing "Size" in a function signature conveys useful meaning that seeing "Pair<foo, bar>" does not. It also lets you write interfaces that operate in the language appropriate for the semantics of the data you're sending around - as Alberth noted with his "area" example, but also even simpler than that: what is a size? It's a width and a height. Not a "first" and a "second." Seeing "thing.width" written in code is lot easier to comprehend than "thing.first," just as seeing "Size" in the parameter list is easier to comprehend than "Pair."

ok, so the bottom line is I should either return a Struct filled with info with inside appropriete variables names like WindowInfo.width and WindowInfo.height or split it into two methods Game->GetWindowWidth() , Game->GetWindowHeight()

Did I got this right? :D

By the way, I added this as well into Utility.h


	template <typename First, typename Second>
	using Pair = std::pair<First, Second>;

and I'm glad to see it everything still compiles without any changes required :P

1 hour ago, MarcusAseth said:

Did I got this right?

Yes.

I'd vote for the first option, since about 80% of the time if you want the width you'll probably also want the height, and there really isn't much to worry about in terms of performance here.

Fixed, thanks :) 

This topic is closed to new replies.

Advertisement