• Advertisement

Archived

This topic is now archived and is closed to further replies.

implicit conversion hell...

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

Can someone please tell me why this code won''t work?
    
// debug\exception.hpp

namespace debug {


	class exception 
	{
	public:
		exception()
		virtual ~exception()

		virtual void output(bool log_to_file = false) const = 0;

	protected:
		static unsigned int instances;
	};


	// things you must define

	extern const char error_title[];
	extern const char log_file_name[];

};

// debug\exception.cpp

#include "exception.hpp"

namespace debug {

	unsigned int exception::instances  = 0;

	exception::exception()
	{
		instances++;
	}

	exception::~exception()
	{

	}
};

// direct_x\exception.hpp



namespace direct_x {

	// exceptions

	class exception
		: public debug::exception
	{
	public:
		explicit exception(const long error_code = 0)

		virtual void output(bool log_to_file = false) const;

		inline const long get_error_code() const
		{  return( error_code );  }

	protected:
		const long error_code;

	};
};


// direct_x\exception.cpp

namespace direct_x {

	exception::exception(const long error_code)
		: error_code(error_code)
	{
	}


	void exception::output(bool log_to_file) const
	{
		std::stringstream text;

		text << std::endl;
		text << "number:     " << exception::instances << std::endl;
		text << "name:       " << typeid(*this).name() << std::endl;
		text << "error code: " << error_code           << std::endl;

		std::string title(debug::error_title);

		if( log_to_file == false )
		{
			// output to the user

			MessageBox(window_handle, text.str().c_str(), title.c_str(), MB_OK);
		}
		else
		{
			// output to the log file

			std::fstream log(debug::log_file_name, std::ios::app / std::ios::out);
			log << title << std::endl;
			log << text.str();
		}
	}
};

// somewhere in another file

if( FAILED( hr ) )
	throw direct_x::surface_creation(hr);
    
The problem occurs at the last line, when trying to throw an object of type direct_x::surface_creation with a long as its only parameter. Here is the compiler error:
quote:
Map.cpp c:\program files\microsoft visual studio\myprojects\battle force\editor\source\map.cpp(417) : error C2440: ''type cast'' : cannot convert from ''long'' to ''class direct_x::surface_creation'' No constructor could take the source type, or constructor overload resolution was ambiguous c:\program files\microsoft visual studio\myprojects\battle force\editor\source\map.cpp(448) : error C2440: ''type cast'' : cannot convert from ''long'' to ''class direct_x::surface_creation'' No constructor could take the source type, or constructor overload resolution was ambiguous

- null_pointer Sabre Multimedia

Share this post


Link to post
Share on other sites
Advertisement
Am I dumb, or am I missing the definition of directx::surface_creation?
I think the problem lies there - you are throwing a non-exception object or something?


Give me one more medicated peaceful moment..
~ (V)^|) |<é!t|-| ~

Share this post


Link to post
Share on other sites
I don't think the problem is with the type of class. In C++ you can throw any class as an exception, it doesn't have to be derived from some sort of 'Exception' class (unlike Java). I think you can even throw an int if you want (although I doubt the usefullness of it).

Perhaps you could do something like this:


if(FAILED( hr )) {
direct_x::surface_creation ex(hr);
throw ex;
}


I've had some troubles with exceptions in the past, and that helped for me.

Dormeur


Edited by - dormeur on June 23, 2000 10:10:26 AM

Edited by - Dormeur on June 23, 2000 10:11:39 AM

Share this post


Link to post
Share on other sites
In C++ you can even throw nothing at all.
I've used code like this in several scenarios.
                
void Foo( void )
{
// Check for errors


// if an error has occurred

throw; // throw up nothing (its more like a dry heave)

}


void Bar( void )
{

try
{
Foo()
}
catch( ... ) // Use ellipsis here instead of an identifier.

{

#ifdef __WIN32__
// Use of Win32 API function for tracing.

OutputDebugString( "An error occured, crucify the programmer." );
#endif

goto Hell;
}

Hell:
return; // return from hell


}






Edited by - Marsupial Rodentia on June 23, 2000 12:34:49 PM

Share this post


Link to post
Share on other sites
quote:
Original post by null_pointer

Can someone please tell me why this code won''t work?

if( FAILED( hr ) )
throw direct_x::surface_creation(hr);

Map.cpp

c:\program files\microsoft visual studio\myprojects\battle force\editor\source\map.cpp(417) : error C2440: ''type cast'' : cannot convert from ''long'' to ''class direct_x::surface_creation''
No constructor could take the source type, or constructor overload resolution was ambiguous



You didn''t provide a definition of direct_x::surface_creation, but I''ll assume that it''s a subclass of direct_x::exception.

If you''re using MSVC, try renaming one of your exception classes slightly. (Like debug::exception to debug::exception_base, or similar.) MSVC has numerous problems with scope and naming that I''ve had to work around. For example:

    
class Polygon {
class Vertex {
};
};

class Polyhedron {
class Vertex {
};
};



The compiler should be able to fully understand that Polygon::Vertex is completely different than Polyhedron::Vertex, but MSVC gets it wrong. I usually end up having to rename the Vertex classes to Polygon_Vertex and Polyhedron_Vertex to make things resolve properly.

Possibly MSVC is messing up similarly named classes in different namespaces in the same way.

---- --- -- -
Blue programmer needs food badly. Blue programmer is about to die!

Share this post


Link to post
Share on other sites
Sorry for not posting a helpful reply, but I want to know how to get a nifty box for my code to show up in, rather than pasting it in the normal message area and having everything after it show up in italics. Thanks!

Share this post


Link to post
Share on other sites
quote:
Original post by Orpheum

Sorry for not posting a helpful reply, but I want to know how to get a nifty box for my code to show up in, rather than pasting it in the normal message area and having everything after it show up in italics. Thanks!


Put everything that is code between a "["source"]" and "["/source"]" tags.

Ignoring the quotation marks of course.

BeOS, "It's da bomb, baby"

Edited by - wrenhal on June 23, 2000 4:45:30 PM

Share this post


Link to post
Share on other sites
It turns out that direct_x::surface_creation was defined like this:


namespace direct_x
{
class surface_creation : public exception {};
}



Of course it wouldn''t work because the derived classes must also declare constructors with arguments, which in this case would be a long. Here is the corrected code:


namespace direct_x
{
class surface_creation : public exception
{ public: surface_creation(const long hr = 0) : exception(hr) {} };
}



If the constructor with arguments isn''t provided, VC thinks you''re trying to do a conversion, like this:


throw long(5); // convert from int to long



mossmoss: VC doesn''t do -too- bad with scoping, but it''s still not good enough. Your vertex example should work fine, but you have to use the scope of the vertex class whenever you refer to it outside of the class, like this:


Polygon::Vertex mypolygon[5];



Just using Vertex by itself outside the class will not give the compiler enough information to tell which Vertex you wish to use.

Here''s a problem for VC:


class file
{
public:
class handle {};

public:
file();

protected:
handle handle;
};

file::file()
: handle() // error here
{
}



VC shouldn''t choke on that, but it does. I think the problem is that VC can''t tell from the context of the statement which handle you are referring to - the type or the variable. It should be obvious to VC which one to use in any statement though.





- null_pointer
Sabre Multimedia

Share this post


Link to post
Share on other sites
quote:
Original post by null_pointer
mossmoss: VC doesn''t do -too- bad with scoping, but it''s still not good enough. Your vertex example should work fine, but you have to use the scope of the vertex class whenever you refer to it outside of the class, like this:


Polygon::Vertex mypolygon[5];





Sorry, but that''s still a problem in my system. I have been using C++ professionally for a number of years and am quite fluent in everything except some of the more "exotic" language features.

Maybe the example I provided is too simple for VC to mess up, but it is representative of the structure I attempted to use. Properly scoping the subclass -- I did essentially what you have shown above -- is what I attempted and what VC failed to properly handle.

Overall, having used a half-dozen other compilers and even working a small bit on the Motorola PPC C/C++ compiler, I find MSVC does fair in compliance to standards, but still misses on many things. Even the simple:

    
for (int i = 0; i < 10; ++i) {
// ...

}

// ...


for (int i = 0; i < 10; ++i) {
// ...

}


will not compile properly on the latest version of MSVC6.

---- --- -- -
Blue programmer needs food badly. Blue programmer is about to die!

Share this post


Link to post
Share on other sites
mossmoss: Can you post that code that VC couldn''t handle? I''d like to see it. (just for fun )

There are only two class/namespace scoping problems that I have run into (and I''ve done just about everything wrong): 1) type and data member in same scope with same name, and 2) a namespace and a class within the namespace with the same name. I already listed #1, but here''s #2 (in case I messed up the description):


namespace virtual_os {
class virtual_os {}; // error here
}



The for loop stuff can easily be gotten around by doing this:

    
{
for( int i=0; i < 10; i++ )
{
// ...

}
}

{
for( int i=0; i < 10; i++ )
{
// ...

}
}



Which is essentially what the new scoping rules do anyway...but I still hope VC 7 does much better with standard support. I''d like to see a few less new MFC features and better standard support.

BTW, if you''re using VC professionally, you can disable the MS extensions, and doing that allows better standard support (as in supporting more features). That''s in the Project Settings dialog box somewhere.





- null_pointer
Sabre Multimedia

Share this post


Link to post
Share on other sites
quote:
Original post by null_pointer
mossmoss: Can you post that code that VC couldn''t handle? I''d like to see it. (just for fun )

The for loop stuff can easily be gotten around by doing this:
......

BTW, if you''re using VC professionally, you can disable the MS extensions, and doing that allows better standard support (as in supporting more features). That''s in the Project Settings dialog box somewhere.




On posting my source... Unfortunately, no, I cannot do that. I work for a game company and, aside from standard reasons for not posting code, this is probably the last place my company would want to see their property.

As far as the scoping, like I indicated in my previous few posts here, my sample itself may have been too simple to fail, but it is the crux of the problem in portions of our code library.

On the loop fix... Yes, that''s pretty much exactly what I''ve done, to add an extra scope around each loop. Or sometimes just to do it C-style and declare the loop variable in the enclosing scope.

Finally, on the MS extensions.... I''ve used MSVC for a while now, but haven''t probed all the depths of configurations. I''ll have to check that; thanks for the suggestions.


---- --- -- -
Blue programmer needs food badly. Blue programmer is about to die!

Share this post


Link to post
Share on other sites

  • Advertisement