Variadic Template Argument...problem o_O

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

this is super strange...

I have this function here:


template<typename TFirst, typename... TArgs>
bool util::LogConsole(const TFirst& first, const TArgs&... rest)
{
	std::cout << first << " ";
	return LogConsole(rest...);
}

bool util::LogConsole()
{
	std::cout << std::endl;
	return false;
}

it's recursive, keep printing "first" and recursively sending the rest, until rest is empty and the overload taking no argument is called, which just print a newline. Ignore the bool return.

Anyway, now I have this code somewhere else:


for (auto& E : Entities) {
		float valx = E->GetPosition().x;//return 751
		float valy = E->GetPosition().y;//return 838
		LogConsole(valx, valy);
	}

Entities is a vector<unique_ptr<Entity>> which currently only contains the derived from Entity player Paddle, so I access the Base class Entity method called GetPosition, which is the center pivot coordinates of the object.

I pass the variable to LogConsole which predictably prints:

Quote

751 838
751 838
751 838
751 838
751 838
751 838
751 838
751 838
751 838
751 838
751 838
751 838
751 838
751 838
751 838
751 838

But not I try to call LogConsole without those 2 variables inbetween, like this:


	for (auto& E : Entities) 
	{
		LogConsole(E->GetPosition().x, E->GetPosition().y);
	}

and watch what kind of output I get! :

Quote

751 17168732
751 17168732
751 17168732
751 17168732
751 17168732
751 17168732
751 17168732
751 17168732
751 17168732
751 17168732
751 17168732
751 17168732
751 17168732
751 17168732
751 17168732
751 17168732
751 17168732

... the y value is an unreasonable value o_o

How is this even possible?! Since only the second value is being affected, my assumption is that there is some weird interplay with the second template parameter, the variadic argument...but I wasn't able to debug it even stepping trough it line by line...can anyone come with an explanation for this really strange behaviour? :S

Advertisement

Here below a main.h with my basic setup , you can run it yourself to see it happening in your console:


#include <iostream>
#include <vector>
#include <memory>
using namespace std;

struct Point {
	int x, y;
};

class Entity {
	float XCenter,YCenter;
public:
	Entity(int x, int y) { XCenter = x; YCenter = y; }
	const Point& GetPosition()const { return Point{ static_cast<int>(XCenter),static_cast<int>(YCenter) }; }
};

class Paddle : public Entity
{
public:
	Paddle(int x, int y) :Entity(x, y) {}
};

void LogConsole()
{
	std::cout << std::endl;
}

template<typename TFirst, typename... TArgs>
void LogConsole(const TFirst& first, const TArgs&... rest)
{
	std::cout << first << " ";
	return LogConsole(rest...);
}

int main()
{
	vector<unique_ptr<Entity>> Entities;
	Entities.push_back(make_unique<Paddle>(751, 838));

	for (auto& E : Entities)
	{
		LogConsole(E->GetPosition().x, E->GetPosition().y);
	}

	return 0;
}

 

Your variadic template is working fine. The problem is you are returning a reference to a temporary:



vvv ref vvv                              vvv temp vvv
const Point& GetPosition()const { return Point{ /* snip */ }; }

 

Quote

How is this even possible?! [...] can anyone come with an explanation for this really strange behaviour?

All things are possible for him who readeth from invalid memory. =P

Spoiler

aa0378579a6701f9ab51a22660ff9b56.jpg

Thanks @Servant of the Lord , I feel like that one shouldn't have slipped past me, damn... :P Probably one more sign that I need to pick up Scott Meyers books as soon as possible

This topic is closed to new replies.

Advertisement