Jump to content
  • Advertisement
Sign in to follow this  
Deyja

Unexplainable overload resolution behavior

This topic is 4730 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

A seemingly simple bit of code had me scratching my head for awhile today. Originally, it looked something like this:
namespace 
{
	typedef boost::mt19937 base_generator_type;
	typedef boost::uniform_int<> distribution_type;
	typedef boost::variate_generator<base_generator_type, distribution_type> gen_type;

	base_generator_type generator;
};

void somefunc()
{
	generator.seed(static_cast<unsigned int>(FuncThatReturnsDouble()));
}


And everything was fine. Several refactorings later, I had a dedicated seed func and it looked like this:
namespace 
{
	typedef boost::mt19937 base_generator_type;
	typedef boost::uniform_int<> distribution_type;
	typedef boost::variate_generator<base_generator_type, distribution_type> gen_type;

	base_generator_type generator;
};

void blah::seed(unsigned int i)
{
        generator.seed(i);
}

//Now in a different file...
void somefunc()
{
	blah::seed(static_cast<unsigned int>(FuncThatReturnsDouble()));
}

The second example does not compile. It generates the totally unhelpful error 'C:\...\boost/random/mersenne_twister.hpp(96) : error C2064: term does not evaluate to a function taking 0 arguments'. The second example seems to be generating a call to generator::seed(generator&), whereas the first calls generator::seed<unsigned int>(unsigned int). The argument to seed is the exact same type in both cases. So; WTF?

Share this post


Link to post
Share on other sites
Advertisement
I can't explain the problem (looks like a compiler bug to me - it seems to consider the template version a better match than a non-template overload with matching type via a typedef, but only when not casting the parameter) but I can offer a couple of workarounds. Any of the following will compile:
  1. Change the parameter type of blah::seed to double and add a static_cast to unsigned int before calling generator.seed().

  2. Leave the parameter type of blah::seed as is and add a static_cast to boost::uint32_t or base_generator_type::result_type before calling generator.seed().

  3. Change the parameter type of blah::seed to boost::uint32_t or base_generator_type::result_type and leave the call to generator.seed() as is.

Enigma

Share this post


Link to post
Share on other sites
Option 1 is the workaround I already did. I solved the problem before I posted this, actually. I'm just figuring out why it happened in the first place. I now think that it has something to do with the result of the cast not being an l-value.

Share this post


Link to post
Share on other sites
I think you're right. Looking into things boost::uint32_t (the parameter type of the non-template single parameter boost::mersenne_twister::seed() function) is a typedef of unsigned long under MSVC++, not unsigned int. So it appears that when the parameter is returned from FuncThatReturnsDouble as an rvalue and passed directly to generator.seed() it undergoes integral conversion to unsigned long before being matched to the template and non-template overloads of boost::mersenne_twister::seed(). However, when blah::seed passes the seed to gerenerator.seed() as an lvalue of type unsigned int it is matched against the template overload of boost::mersenne_twister::seed() before undergoing lvalue-to-rvalue conversion followed by integral conversion.

That said, my standardese isn't as hot as some around here, so if anyone would like to confirm/correct...

Enigma

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!