Jump to content
  • Advertisement
Sign in to follow this  
kerilynne

Creating a shared pointer out of typename T_

This topic is 3820 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Here is the code, I'll bold the function I'm working with: I was just changing the resource manager to seperate the add resource method from the request resource method and creating a new method entirely, Manage_Resource.
#ifndef RESOURCE_MANAGER_H
#define RESOURCE_MANAGER_H

#include <vector>
#include <map>
#include <string>
#include <boost\shared_ptr.hpp>
#include <boost\weak_ptr.hpp>
#include <iostream>

template< typename T_ >
class Resource_Manager
{  

public:

	typedef T_ value_type; // std library convention 

	typedef boost::shared_ptr<T_> Resource_Ptr;
	typedef boost::weak_ptr<T_> Resource_Observer;
	typedef std::map< std::string, Resource_Ptr > Resource_Map;
	Resource_Manager<T_>() {};
	~Resource_Manager<T_>() {};

	bool Manage_Resource(const std::string & name, T_)
	{
		Resource_Map::iterator it = mResources.find(name);
		if (it == mResources.end())
		{
			Resource_Ptr Raw_Resource(T_);
			mResources.insert(std::make_pair(name,  Raw_Resource));
			return true;
		}
		else
		{
			return false;
		}
	}

	Resource_Observer Request_Resource(const std::string & name)
	{
		Resource_Map::iterator  it = mResources.find(name);

		if (it == mResources.end())
		{
			std::cout << "This resource does not exist!";
			/*
			Resource_Ptr Raw_Resource(new T_);
			mResources.insert(std::make_pair(name, Raw_Resource));
			Resource_Observer Resource(Raw_Resource);
			return Resource;
			*/
		}
		else
		{
			return Resource_Observer(it->second);
		}
	}

	void Remove_Resource(const std::string & name)
	{
		Resource_Map::iterator it = mResources.find(name);

		if (it != mResources.end())
		{
			mResources.erase(it);
		}
	}

private:
	Resource_Map  mResources;
};

#endif

That code compiled fine but now I'm trying to use it like so, and getting compiler errors:


	void initialize_player(std::string player_id)
	{
		Player * new_player = new Player(player_id);
		m_rPlayers.Manage_Resource( player_id, new_player );
	}
I'm not quite sure what I'm doing wrong, but here is the first few errors it generates:
error C2664: 'Resource_Manager<T_>::Manage_Resource' : cannot convert parameter 2 from 'Player *' to 'Player'
        with
        [
            T_=Player
        ]
        No constructor could take the source type, or constructor overload resolution was ambiguous
I've tried switching parameters and changing pointers to references to values and I can't get any entries to work, any idea what I'm doing wrong?

Share this post


Link to post
Share on other sites
Advertisement
You are passing a Player pointer to Resource_Manager<Player>::Manage_Resource's second argument, which is of type Player.

You need to either change the argument to a pointer, or preferably a smart pointer.

Share this post


Link to post
Share on other sites
You have the line bool Manage_Resource(const std::string & name, T_), which defines a function taking two parameters. The second parameter is of type T_ (presumably Player in this instantiation). It has no name and is not used by the function. Then you have the lines Player * new_player = new Player(player_id); m_rPlayers.Manage_Resource( player_id, new_player );, the second of which passes a pointer to a Player (instead of a Player) to the function. This is exactly what the error message is telling you. Learning to interpret these error messages (they're not Greek) will be a useful way to spend your time.

Share this post


Link to post
Share on other sites
I changed the parameter like this before but it led to another error that made me backtrack... But I realize that extra error was just me not completing the function by creating the shared pointer out of type instead of T_.

I've changed the parameter for manage_resource to take a T_ * type in the second parameter.


bool Manage_Resource(const std::string & name, T_ * type)
{
Resource_Map::iterator it = mResources.find(name);
if (it == mResources.end())
{
Resource_Ptr Raw_Resource(type);
mResources.insert(std::make_pair(name, Raw_Resource));
return true;
}
else
{
return false;
}
}




This works :)

I just wasn't paying close enough attention to details I suppose, in the line Resource_Ptr Raw_Resource(type) there used to be a T_ there, which was causing extra errors when I actually passed a pointer, which I'm doing now.

But now that I see it it is fixed!

Share this post


Link to post
Share on other sites
Quote:
Original post by kerilynne
The reason I'm posting is because the error is misleading.


Except that it wasn't - C++ is just evil.
'Resource_Manager<T_>::Manage_Resource' : cannot convert parameter 2 from 'Player *' to 'Player'
Obvious... You're passing Player *, and second parameter of function accepts Player.

The following however:
No constructor could take the source type, or constructor overload resolution was ambiguous
is why C++ is tricky.

Consider this:
void foo( const std::string & s );

foo("Hello World");


What would happen if your Player class were defined as follows:
struct Player
{
Player() {};
Player( Player * other ) {} // special copy constructor
};


The code you posted would compile, and lots of hilarity would ensue.

What would happen would be the following:
// template instantiation for Player
bool Manage_Resource(const std::string & name, Player p)
{
};

...

void initialize_player(std::string player_id)
{
Player * new_player = new Player(player_id);
Player __temp( new_player ); // generated by compiler
m_rPlayers.Manage_Resource( player_id, __temp ); // passed by value
}


This is why it's a good idea to mark non-default constructors as explicit. The reason your compiler failed was because after trying to do the above, the following happened:
void initialize_player(std::string player_id)
{
Player * new_player = new Player(player_id);
Player __temp( new_player ); // E2664: Player has no constructor taking Player *
m_rPlayers.Manage_Resource( player_id, __temp );
}


The compiler in this case reported the correct error, but the problem comes from a direction you didn't expect or were aware of.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!